home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-06-25 | 93.1 KB | 3,626 lines | [TEXT/CWIE] |
- /*==============================================================================
- Project: POV-Ray
-
- Version: 3
-
- File: Pov.c
-
- Description:
- This file contains the main program and most other Macintosh-specific
- routines for the Persistence Of Vision raytracer (POV-Ray.)
- ------------------------------------------------------------------------------
- Mac Authors:
- Thomas Okken, David Lichtman, Glenn Sugden
- Jim Nitchals, David Harr, Eduard [esp] Schwan
- ------------------------------------------------------------------------------
- from Persistence of Vision(tm) Ray Tracer
- Copyright 1996 Persistence of Vision Team
- ------------------------------------------------------------------------------
- NOTICE: This source code file is provided so that users may experiment
- with enhancements to POV-Ray and to port the software to platforms other
- than those supported by the POV-Ray Team. There are strict rules under
- which you are permitted to use this file. The rules are in the file
- named POVLEGAL.DOC which should be distributed with this file. If
- POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- Forum. The latest version of POV-Ray may be found there as well.
-
- This program is based on the popular DKB raytracer version 2.12.
- DKBTrace was originally written by David K. Buck.
- DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- ------------------------------------------------------------------------------
- More Info:
- This Macintosh version of POV-Ray was updated and compiled by Eduard Schwan
- and now builds under Apple MPW 3.3.x, Metrowerks CodeWarrior CW6+, and
- Symantec C 7, for the 68K and Power Macintosh.
- The Macintosh code was based (loosely) on the original DKB 0.5 port by
- Thomas Okken and David Lichtman, with some help from Glenn Sugden.
- Jim Nitchals was instrumental in getting 1.0 out, Jim and Eduard jointly
- pulled off 2.x with help from Dave Harr for initial Balloon help and the
- custom palette code, and 3.0 was done by Eduard Schwan.
-
- For bug reports regarding the Macintosh version, you may contact:
- Eduard [esp] Schwan -- esp Software
- CompuServe: 71513,2161
- Internet: 71513.2161@compuserve.com
- ------------------------------------------------------------------------------
- Change History:
- 920815 [jln] version 1.0 Mac released.
- 920908 [esp] version 1.1 alpha Mac
- 921228 [esp] version 1.1 beta Mac
- 930113 [esp] 1.1b20 release, looks pretty stable to me
- 930725 [esp] version 1.75b3 released (cancel parse bug fixed)
- 930903 [esp] version 1.91b2 released (VIB bug fixed)
- 930911 [esp] version 1.91b4 released (include path uses SFGetFile now)
- 930918 [esp] version 1.92b1 released (AppFriendly works better, ImageWindPos restored OK)
- 930929 [esp] version 1.94b2 released (removed QuickTime "No Image Comp" warning)
- 931001 [esp] version 2.0 finished (Released on 10/4/93)
- 931005 [esp] version 2.01b fixed cmd-O bug (every other file open fails)
- 931005 [esp] version 2.01b undo & redo scroll window to where the action is
- 931018 [esp] version 2.01b Changed RenderOpts AutoBound from checkbox to popup,
- display credits at startup, not 1st render, fixed include prefs logic
- 931119 [djh] 2.0.1 source conditionally compiles for PPC machines, keyword __powerc
- 940204 [esp] 2.2 prepare for release - bound slabs default OFF
- 940416 [PFS] 2.2.1 greatly reworked to clean up PPC support and provide CodeWarrior projects
- 940430 [esp] Preliminary 3.0a1 work
- 940520 [esp] 2.2+ updated for Metrowerks DR/3 release
- 950105 [esp] 3.0a13 updated for Metrowerks CW5 and Symantec 7.0.3
- 950629 [esp] 3.0a18 continue splitting this monolithic file into other smaller files
- 960210 [esp] 3.0b5 Added beta timeout code, in preparation for public beta
- 960421 [esp] 3.0b6 Loosened coupling to editor, so I could add the TE32K code.
- 960714 [esp] 3.0F1 POV-Ray 3.0 final let loose on the world, finally!
- 970502 [tf] 3.0.2 Thorsten Froehlich(106325,3677) contributed undo/redo code
- ==============================================================================*/
-
- #if !defined(POVMACHEADERS_PCH)
-
- /*==== POV-Ray std headers ====*/
- #include "config.h"
-
- #include "PovMac.h"
- #include "povray.h" // for alt_main
-
-
- /*==== Standard C headers ====*/
- #include <stdlib.h>
- #include <setjmp.h>
-
-
- /*==== Macintosh-specific headers ====*/
-
- #include <Types.h>
- #include <Controls.h>
- #include <Dialogs.h>
- #include <Files.h>
- #include <Memory.h>
- #include <Menus.h>
- #include <Events.h>
- #include <OSUtils.h>
- #include <Packages.h>
- #include <PictUtils.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include <Windows.h>
- #include <AppleEvents.h>
- #include <scrap.h>
- #include <sound.h>
- #include <DiskInit.h>
- #include <Gestalt.h>
- #include <Folders.h>
- #include <Balloons.h> /* kHMHelpMenuID */
- #include <errors.h> /* dupFNErr, etc */
- #include <fonts.h>
- #include <segload.h> /* UnloadSeg */
- #include <eppc.h> /* kHighLevelEvent */
- #include <traps.h> /* _Unimplemented */
- #include <string.h> /* strcpy/cat */
- #include <toolutils.h> /* BitTst, etc */
-
- #if defined(powerc) || defined (__powerc)
- #include <CodeFragments.h> /* kUnresolvedAddress */
- #endif
-
- #if defined (applec) || defined(__MWERKS__)
- #include <strings.h> /* p2cstr */
- #endif // apple
-
- // Debug with profiler
- #if defined(THINK_C) && defined(NEEDS_PROF)
- #include <profile.h>
- #endif
-
-
- /*==== POV-Ray text editor header ====*/
- #include "TextEditor.h"
- #include "UndoRedoSystem.h"
-
-
- /*==== POV Mac Library routines =====*/
- #include "UtilLib.h"
-
- #include "ArgvTrix.h"
- #include "VolsPaths.h"
- #include "FileQueue.h"
- #include "AEUtils.h"
-
- #include "Animate.h"
- #include "SaveCmpPict.h"
- #include "FileQueue.h"
- #include "ImageWindow.h"
- #include "ProgressDialog.h"
- #include "TemplateMenu.h"
- #include "AboutBox.h"
- #include "SplashScreen.h"
- #include "OptOut.h" // DISTRIBUTION_MESSAGE
-
- #include "AppPrefs.h"
- #include "FilePrefs.h"
-
- #endif // POVMACHEADERS_PCH
-
- /*==== General definitions ====*/
-
- // preview picture rsrc id
- #define kDemoPICTrsrcID 1001
-
- #if defined(applec)
- /* entry point to %a5init segment, for disposal after init */
- extern void _DataInit();
- #endif // applec
-
- #if defined(__MWERKS__)
- #include "unix.mac.h" // for _fcreator, _ftype (setting file type)
- #endif
-
-
- /*==== Global variables (external scope) ====*/
-
- #if defined(__MRC__)
- QDGlobals qd;
- #endif
-
- p2w_WindowPtr_t gp2wWindow = NULL; // the Status (text) window
-
- Boolean gHasAppleEvents = false; // Apple Events available for doing shutdown?
- Boolean gHas32BitQD = false; // is 32 bit Quickdraw available for depth & dithering
- Boolean gHasPictUtils = false; // is Picture Utils (extract best palette) avail?
- Boolean gHasImageCompressionMgr = false; // Is image compression available?
- Boolean gHasQuickTime = false; // Is QuickTime available?
- long gQTVersion; // QuicktTime version from Gestalt
-
- Boolean gInBackground = false; // is the program currently switched out
- Boolean gDoingRender; // for determining the menu states
- Rect gDragBounds; // window dragging boundary
-
- StringPtr gDistMessage; // concatenated from OPTIONS.H strings
-
- Boolean gDoingBatchODOCs = false; // in the middle of ODOC, postpone other odocs
-
- Boolean gCanUndo = false; // can we undo this operation?
- Boolean gCanRedo = false; // can we redo this operation?
-
- short gAppRefNum = -1; // The application's resource file refnum
-
- Str31 gPictFname; // name of pict output file
- Str31 gOutFname; // name of other output file
-
- ComponentInstance gtheSCComponent = NULL;
-
- /*==== Global variables (local scope) ====*/
-
- static Boolean gAutoShutdown = false; // flag for auto-shutdown on completion
- static Boolean gBeginRendering = false; // True when user picks Render from menu
- static SndChannelPtr gSndChannelPtr = NULL; // Beep this!
-
- // Animation-related
- static Boolean gInAnimationLoop = false; // True when rendering an animation file
- static AnimRec_t gAnimRec; // current animation frame/clock info
-
-
- static jmp_buf gSetJmpEnv; // exit state
-
- // resource file reference numbers
- static short SrcResRefNum = kRsrcFileClosed;
-
- static long gPrevTickCount; // Time of last WNE time slice
- static long gWNEReleaseTicks; // how long to yield to other apps
- static RgnHandle gCursorRgn;
-
- static MenuHandle myMenus[num_of_menus];
- static MenuHandle mySubMenus[num_of_submenus];
- static EventRecord gTheEvent;
-
- static Boolean gQuit = false;
- static short gPaused = 0;
-
- static short gRenderedOK = false;
- static long TargetTicks;
-
- // out-of-mem reserve space, for MEMALLOC.C
- #define RESERVE_MEM_SIZE 100000L
-
- // stack tracking
- static long gStackBase;
- static long gStackMax;
-
-
-
- /*==== BETA timeout stuff ====*/
- // uncomment this line to turn on the beta-timeout code
- // #define DO_BETA
-
- #ifdef DO_BETA
- #include <Time.h>
- #define rDlg_BetaTimeout 6969 // Freudian dialog ID
- #define BETA_YEAR 97 // This is the y/m/d it will time out after
- #define BETA_MONTH 6
- #define BETA_DAY 30
- static float gTimeoutFlag = 0.0; // this will be set to >0 if NOT OK to run
- static struct tm *gThetmPtr;
- #endif // DO_BETA
-
-
-
- // ---------------------------------------------------------------------
- // return the state of the Quit flag
- #pragma segment Main
-
- Boolean AppIsQuitting(void)
- {
- return gQuit;
- } // AppIsQuitting()
-
-
- // ---------------------------------------------------------------------
- // turn ON the Quit flag
- #pragma segment Main
-
- void SetAppQuit(void)
- {
- gQuit = true;
- } // SetAppQuit()
-
-
- // ---------------------------------------------------------------------
- // Set default (current) dir to that of the POV-Ray app, so any C-library
- // file open calls will look for files in this directory.
- OSErr SetCurrentDirToAppDir(void)
- {
- OSErr anError;
- FSSpec myAppSpec;
- ProcessSerialNumber myPSN;
- ProcessInfoRec myProcessRec;
-
- // Find info about our process
- myPSN.highLongOfPSN = 0;
- myPSN.lowLongOfPSN = kCurrentProcess; // ourself
- myProcessRec.processAppSpec = &myAppSpec;
- myProcessRec.processInfoLength = sizeof(myProcessRec);
- myProcessRec.processName = NULL;
- anError = GetProcessInformation(&myPSN, &myProcessRec);
- // set current directory to the application directory
- if (!anError)
- anError = HSetVol(NULL, myAppSpec.vRefNum, myAppSpec.parID);
- return anError;
- } // SetCurrentDirToAppDir
-
-
- // ---------------------------------------------------------------------
- // Dispose and recreate an empty file list queue
- static void HaltFileQ()
- {
- // halt any multi-doc processes
- gDoingBatchODOCs = false;
-
- FileQ_d(); // Tear down ODOC File Queue
- FileQ_c(); // re-create it, empty
- } // HaltFileQ
-
-
- // ---------------------------------------------------------------------
- // Calculate MultiFinder yield time as a function of hogginess.
- // If the user is making POV-Ray extra friendly, yield more background
- // ticks. If user's making us extra hoggy, return right away.
- //APGet_TimeSlice() gWNEReleaseTicks
- // 1 4
- // 2 3
- // 3 2
- // 4 1
- // 5 0
- static void CalcCpuReleaseTicks(Boolean AllowVerbose)
- {
- // gWNEReleaseTicks = # of ticks to allow for other apps before returning
- gWNEReleaseTicks = (eThrottle_Highest - APGet_TimeSlice());
- if ( AllowVerbose )
- if ( (**gPrefs2Use_h).progress >= eProgDebug )
- printf("-d AppPriority=%ld, ReleaseTimes=%ld\n", APGet_TimeSlice(), gWNEReleaseTicks);
- }
-
-
- // ---------------------------------------------------------------------
- // Convert current date/time into an ASCII C string for display
- static char * GetDateTimeString(char *pbuff)
- {
- unsigned long dtsecs;
- char tbuff[64];
-
- // Does anybody really know what time it is?
- GetDateTime(&dtsecs);
-
- // convert date to string
- IUDateString(dtsecs, shortDate, (StringPtr)tbuff);
- p2cstr((StringPtr)tbuff);
- strcpy(pbuff, tbuff);
-
- // put date/time separator in buffer
- strcat(pbuff, " ");
-
- // convert time to string
- IUTimeString(dtsecs, true, (StringPtr)tbuff);
- p2cstr((StringPtr)tbuff);
- strcat(pbuff, tbuff);
-
- // "give user his filled buffer back"
- return (pbuff);
- } // GetDateTimeString
-
-
- // ------------------------------------------------------------------
- // Display some general debugging information, if user has dubugging flag turned on
- #pragma segment Inits
-
- static void DisplayConfigInfo(void)
- {
- long gestaltResponse;
- OSErr anError = noErr;
-
- printf("! --- General System Information ---\n");
- printf("! Available Memory: %d KBytes\n", FreeMem()/1024);
-
- if (Gestalt(gestaltSystemVersion, &gestaltResponse) == noErr)
- printf("! MacOS system version: %04lx\n", gestaltResponse);
-
- printf("! AppleScriptExists: %d\n", gAppleScriptAvail);
-
- // QuickTime and ImageCompression mgr
- printf("! QuickTimeVersion: 0x%08lx ImageCompressionExists: %d\n", gQTVersion, gHasImageCompressionMgr);
-
- if (Gestalt(gestaltSysArchitecture, &gestaltResponse) == noErr)
- {
- printf("! CPU type: ");
- if (gestaltResponse == gestaltPowerPC)
- printf("PowerPC\n");
- else
- {
- // what kind of 68k CPU?
- Gestalt(gestaltProcessorType, &gestaltResponse);
- printf("680%2d",(gestaltResponse-gestalt68000)*10); // 00,10,20...
- // what kind of FPU?
- printf(" FPU type: ");
- Gestalt(gestaltFPUType, &gestaltResponse);
- if (gestaltResponse == gestaltNoFPU)
- printf("None\n",(gestaltResponse-gestalt68000)*10);
- else if (gestaltResponse == gestalt68040FPU)
- printf("Built-in\n",(gestaltResponse-gestalt68000)*10);
- else
- printf("6888%1d\n",gestaltResponse);
- }
- }
-
- // Check for Software FPU installed if compiled for 68K (no problem if on PPC)
- #if !defined(powerc) && !defined (__powerc)
- {
- if (Gestalt('FPUE', &gestaltResponse) == noErr)
- {
- printf("! NOTE: 68K SoftwareFPU extension detected...\n");
- printf("! (Floating point operations are emulated in software.)\n");
- printf("! NOTE: SoftwareFPU does not work well on 68LC040 Macs!\n\n");
- }
- }
- #endif
- }
-
-
- // ---------------------------------------------------------------------
- static void DoShutdownMac()
- {
- Cooperate(true);
-
- if (gHasAppleEvents)
- SendAEShutdown();
- else
- SysBeep(1);
-
- Cooperate(true);
-
- } // DoShutdownMac
-
-
- // ---------------------------------------------------------------------
- // Play a nifty "finished" sound
- static void PlayNotifySound(void)
- {
- // if you don't have universal headers...
- // #define SndListHandle Handle
- SndListHandle theSndHandle;
- OSErr anError;
- short soundResID;
- ResType soundResType;
- Str255 soundName;
-
- // Get the user's chosen sound ID from prefs
- soundResID = APGet_AllDoneSoundID();
- // load that sound
- theSndHandle = (SndListHandle)GetResource(soundListRsrc, soundResID);
- // play it
- if (theSndHandle)
- {
- if ((**gPrefs2Use_h).progress == eProgDebug)
- {
- GetResInfo((Handle)theSndHandle, &soundResID, &soundResType, soundName);
- p2cstr(soundName);
- printf("\n### Sound playing is '%s' (%ldK bytes)\n\n",
- soundName, GetResourceSizeOnDisk((Handle)theSndHandle)/1024L);
- }
- anError = noErr;
- // Create a sound channel first time through
- if (gSndChannelPtr == NULL)
- anError = SndNewChannel(&gSndChannelPtr, sampledSynth, 0L, NULL);
- // Normally we can play the sound asynchronously, but if we're automatically
- // quitting, we need to play synchronously, so we don't quit the app
- // while still playing the sound (which simply truncates the sound.)
- if (!anError)
- anError = SndPlay(gSndChannelPtr, theSndHandle, !AppIsQuitting());
- }
- } // PlayNotifySound
-
-
- // ---------------------------------------------------------------------
- // Show an ALL DONE dialog
- static void ShowNotifyDialog(void)
- {
- if (!gRenderedOK)
- // rendering error
- (void)DisplayModalDialog(143, ok, 0, NULL, 0, ewcDoCentering, eSameAsPassedWindow);
- else
- // completed OK
- (void)DisplayModalDialog(142, ok, 0, NULL, 0, ewcDoCentering, eSameAsPassedWindow);
- } // ShowNotifyDialog
-
-
-
- // ---------------------------------------------------------------------
- // Change the type/creator of the other output file
- static void ChangeFileType(void)
- {
- OSErr anError;
- FInfo myFileInfo;
-
- // Get file info, so we can change it
- anError = GetFInfo ((StringPtr)gOutFname, gSrcWind_VRefNum, &myFileInfo);
-
- if (anError==noErr)
- {
- switch ((**gPrefs2Use_h).outfileType)
- {
- case eOutfTarga: // uncompressed targa
- case eOutfTargaC: // compressed targa
- myFileInfo.fdType = 'TPIC';
- myFileInfo.fdCreator = (**gPrefs2Use_h).targaFileCreator;
- break;
- case eOutfPNG: // PNG
- myFileInfo.fdType = 'PNG ';
- myFileInfo.fdCreator = (**gPrefs2Use_h).targaFileCreator;
- break;
- case eOutfPPM: // Unix ppm file
- myFileInfo.fdType = 'PPGM';
- myFileInfo.fdCreator = (**gPrefs2Use_h).targaFileCreator;
- break;
- }
-
- anError = SetFInfo ((StringPtr)gOutFname, gSrcWind_VRefNum, &myFileInfo);
- }
- } // ChangeFileType
-
-
- // ---------------------------------------------------------------------
- // Set up to call the renderer, call it, and clean up after it returns
- static void call_main(int argc, char **argv)
- {
- char timeBuffer[128];
-
- dispose_virtual(); // deletes virtual file
- KillOffscreen(); // delete any previous offscreens
-
- Cooperate(true);
- Cooperate(true);
-
- gPrevTickCount = MAC_TICKS;
- gRenderedOK = true; /* presume that rendering will finish OK */
- // reset our stack-watcher
- gStackMax = 0;
-
- p2cstr(gSrcWind_FileName);
- printf("-- [Start] File=%s, Time=%s\n", gSrcWind_FileName, GetDateTimeString(timeBuffer));
- c2pstr((char*)gSrcWind_FileName);
-
- #if defined (USE_MEM_HANDLES)
- // turn ON use of temp memory allocation (MEMALLOC.C)
- // too extreme for now... need an Application preference... [esp]
- // UseTempMem(TRUE);
- #endif
-
- if (setjmp(gSetJmpEnv) == 0)
- {
- // Call the POV-Ray engine to actually render the image
- alt_main(argc, argv);
- }
- // Return here if 'exit()' called
-
- // turn OFF use of temp memory allocation (MEMALLOC.C)
- #if defined (USE_MEM_HANDLES)
- // UseTempMem(FALSE);
- #endif
-
- if (gRenderedOK && (**gPrefs2Use_h).outfileType > 0)
- ChangeFileType(); /* change type and creator of the output file */
-
- InvalRect_ImageWindow(true);
-
- // how much stack space used?
- if ((**gPrefs2Use_h).progress >= eProgMac)
- {
- printf("-- [Stack] Total Stack space used = %ld bytes\n", gStackMax);
- }
-
- // FINISHED!
- p2cstr(gSrcWind_FileName);
- printf("-- [Finish] File=%s, Time=%s\n", gSrcWind_FileName, GetDateTimeString(timeBuffer));
- c2pstr((char*)gSrcWind_FileName);
-
- // Give a quick breath after each render
- // NOTE: Do this before setting gDoingRender back to false, so that the menu
- // allows cmd-period to halt the render, especially during animations. There
- // window activates too, so call it a few times.
- Cooperate(true);
- Cooperate(true);
- Cooperate(true);
-
- // Whenever we are done rendering a file, pop the status window to the bottom
- // now that we have user-controlled auto-scrolling, may not want to do this [esp]
- // p2w_ScrollEnd(gp2wWindow);
-
- gDoingRender = false;
- } // call_main
-
-
-
- // ---------------------------------------------------------------------
- // Force all menus to be disabled
- void DisableMenus(void)
- {
- int i;
-
- for (i = 1; i < num_of_menus; i++)
- DisableItem(myMenus[i], 0);
-
- // Don't disable about under 7.0, otherwise OS turns OFF ALL MENUS,
- // including help, app, & script menus!
- EnableItem(myMenus[apmn_ID - menu_offset], apmn_about);
-
- HiliteMenu(0);
- DrawMenuBar();
- } // DisableMenus
-
-
- // ---------------------------------------------------------------------
- // Force all menus to be enabled
- void EnableMenus(void)
- {
- int i;
- for (i = 1; i < num_of_menus; i++)
- EnableItem(myMenus[i], 0);
-
- HiliteMenu(0);
- DrawMenuBar();
- } // EnableMenus
-
-
-
-
-
- // ---------------------------------------------------------------------
- // prompt for which line # to go to, and go to it
- #define kItem_LineNum 4
- static void choose_goto_line(void)
- {
- short dummyInt, line_to_go;
- short itemHit;
- DialogPtr myDialog;
- Rect displayRect;
- ControlHandle editTextH;
- char s1[128];
-
- DisableMenus();
-
- line_to_go = 1; /* for now */
- myDialog = GetNewDialog(150, NULL, (WindowPtr) -1);
- GetDialogItem(myDialog, kItem_LineNum, &dummyInt, (Handle *) &editTextH, &displayRect);
- sprintf(s1, "%d", line_to_go);
- SetDialogItemText((Handle)editTextH, c2pstr(s1) );
- SelectDialogItemText(myDialog, kItem_LineNum, 0, 32767);
- PositionWindow(myDialog, ewcDoCentering, eSameAsPassedWindow, (WindowPtr)gp2wWindow);
- // set the standard action for OK/cancel buttons
- SetupDefaultDialogButtons(myDialog, ok, cancel);
- ShowWindow(myDialog);
- do
- {
- ModalDialog(GetStdModalFilter(), &itemHit);
- }
- while (itemHit != ok && itemHit != cancel);
-
- if (itemHit == ok)
- {
- GetDialogItemText((Handle)editTextH, (StringPtr)s1);
- p2cstr((StringPtr)s1);
- line_to_go = atoi(s1);
- if (line_to_go<1)
- line_to_go=1;
- else if (line_to_go>32767)
- line_to_go=32767;
- }
- DisposeDialog(myDialog);
- if (itemHit == ok)
- {
- SelectWindow(gSrcWind_Window);
- GotoSrcWindLine(line_to_go);
- }
-
- EnableMenus();
- } // choose_goto_line
-
-
- // ---------------------------------------------------------------------
- // This is what is really called if exit() is called
- #define kEXIT_USERBRK 2 // returned from POV-Ray engine if user cancelled
- void catch_exit(int n)
- {
- // exit(0) is not a syntax error, only jump to line # if <>0
- if (n != 0)
- {
- gRenderedOK = 0;
- // if error & in main file, then go to line number
- if (n != kEXIT_USERBRK) // don't jump to line number if user abort (#2)
- /* if (Include_File_Index == 0) -- no more access to this var, do it always */
- {
- // Show errors at end of status window
- p2w_ScrollEnd(gp2wWindow);
- SelectWindow((WindowPtr)gp2wWindow); // second to front...
- // hilite line number in source window
- GotoSrcWindLine(Token.Token_Line_No+1);
- SelectWindow(gSrcWind_Window); // front window
- }
- }
-
- // We want to clear out the queue of upcoming files to render if
- // 1. User doesn't want to continue if errors happen
- // or
- // 2. If it is a user-break.
- if ((APGet_KeepGoingOnErrors() == FALSE) || (n == kEXIT_USERBRK))
- HaltFileQ();
-
- longjmp(gSetJmpEnv, 1);
- } // catch_exit
-
-
-
- // ---------------------------------------------------------------------
- static void DoLookup()
- {
- if (FrontWindow() == gSrcWind_Window)
- {
- // First, copy the selection to the clipboard
- SrcWindCopySelToClipboard();
-
- // Now, switch to POV-Reference if it is there
-
- // (POV-Reference is an on-line help reference, which
- // was going to be the stack that came with the book
- // "Ray Tracing for the Macintosh CD", but we didn't
- // get the AppleEvent hooks into the reference. Feel
- // free to write one as an AppleGuide for example. :-) [esp]
- }
- } // DoLookup
-
-
- #pragma mark -
-
- // ---------------------------------------------------------------------
- // set up the POV-Ray engine's argc/argv parameters from file settings
- static void SetupRenderArgs(void)
- {
- Boolean allowBitsPerColor;
- char *s1, *s2;
- char rawFileName[32];
-
- // --------------------------------
- // create a couple of temporary buffers for building arg-lists
- // --------------------------------
- s1 = (char*)NewPtr(256);
- s2 = (char*)NewPtr(256);
- if (!s1 || !s2)
- {
- (void)DisplayModalDialog(kdlog_GenericFatalErr, ok, 0, "Out of memory building command line",
- memFullErr, ewcDoCentering, eMainDevice);
- SetAppQuit();
- return;
- }
-
- // --------------------------------
- // set current directory to that of scene file
- // --------------------------------
-
- SetVol(NULL, gSrcWind_VRefNum);
-
- // --------------------------------------------------------
- // Now start building the parameters
- // --------------------------------------------------------
-
- // --------------------------------
- // argv[0] is always the program name, not used, but cute
- // --------------------------------
- AddArg("POV-Ray");
-
- // --------------------------------
- // get input file and strip off any suffix
- // --------------------------------
- BlockMove(gSrcWind_FileName, rawFileName, gSrcWind_FileName[0]+1); // pascal string copy
- p2cstr((StringPtr)rawFileName); // convert to C string
-
- // --------------------------------
- // set up input file arg
- // --------------------------------
- sprintf(s1, "Input_File_Name=%s", rawFileName);
- AddArg(s1);
-
- // --------------------------------
- // set up raw output file
- // --------------------------------
- {
- short theLen, suffixLen;
- char *dotPtr;
- // look for .POV suffix on input file name
- dotPtr = strrchr(rawFileName, '.');
- theLen = strlen(rawFileName);
- if (dotPtr != NULL)
- {
- *dotPtr = '\0'; // terminate string here, on the dot
- }
- // Also make sure we have at least 5 or 4+5 characters available on end now,
- // 5 for the ".pict" and optionally 4 more for the animation digits
- theLen = strlen(rawFileName);
- if ((**gPrefs2Use_h).doAnimation)
- suffixLen = 4+5; // add "nnnn.pict"
- else
- suffixLen = 5; // add ".pict"
-
- if (theLen+suffixLen > 31) // max file name length
- {
- rawFileName[31-suffixLen] = 0; // terminate string here
- }
- // add frame value to filename if animating
- if ((**gPrefs2Use_h).doAnimation)
- {
- sprintf(s1, "%04d", GetCurrFrameVal());
- strcat(rawFileName, s1);
- }
- }
-
- // --------------------------------
- // output file name (PICT)
- // --------------------------------
-
- // Put raw file name into pict file
- strcpy((char*)gPictFname, rawFileName);
- // add suffix
- strcat((char*)gPictFname, ".pict");
- // convert to Pascal string
- c2pstr((char*)gPictFname);
-
- // --------------------------------
- // output file name/type (other)
- // --------------------------------
-
- // If image is too big for PICT & user is only saving to pict, force other file output!
- // NOTE: This is a grody hack until we fix VIB to work with big images! [esp]
- if (gTooBigForPICT && ((**gPrefs2Use_h).outfileType == eOutfNone))
- {
- (**gPrefs2Use_h).outfileType = eOutfPNG;
- }
-
- // Put raw file name into other output filename
- strcpy((char*)gOutFname, rawFileName);
-
- // add file type suffix (pict, png, targa or ppm)
- allowBitsPerColor = FALSE; // until disproved
- switch ((**gPrefs2Use_h).outfileType)
- {
- case eOutfNone: // PICT only
- AddArg("Output_To_File=off");
- allowBitsPerColor = TRUE; // PICT
- break;
- case eOutfTarga: // uncompressed targa
- AddArg("Output_File_Type=T");
- strcat((char*)gOutFname, ".tga");
- break;
- case eOutfTargaC: // compressed targa
- AddArg("Output_File_Type=C");
- strcat((char*)gOutFname, ".tga");
- break;
- case eOutfPNG: // PNG
- AddArg("Output_File_Type=N");
- strcat((char*)gOutFname, ".png");
- allowBitsPerColor = TRUE;
- break;
- case eOutfPPM: // Unix ppm file
- AddArg("Output_File_Type=P");
- strcat((char*)gOutFname, ".ppm");
- break;
- default:
- strcat((char*)gOutFname, ".<?>");
- break;
- }
- // write output file name arg
- sprintf(s1, "Output_File_Name=%s", (char*)gOutFname);
- AddArg(s1);
- // convert to Pascal string
- c2pstr((char*)gOutFname);
-
- // --------------------------------
- // bits per color for certain image file types (PNG/PICT)
- // --------------------------------
- if (allowBitsPerColor)
- {
- sprintf(s1, "Bits_Per_Color=%d", (int)(**gPrefs2Use_h).bitsPerColor);
- AddArg(s1);
- }
-
- // --------------------------------
- // Do alpha channel?
- // --------------------------------
- sprintf(s1, "Output_Alpha=%d", (**gPrefs2Use_h).doAlphaChannel);
- AddArg(s1);
-
- // --------------------------------
- // display format always on for Mac
- // (This turns on the display calls & image window)
- // --------------------------------
- AddArg("Display=on");
-
- // --------------------------------
- // exit enable on, but we breathe via COOPERATE too
- // (this is mostly turned on for aesthetics, so that the
- // status window shows it ON)
- // --------------------------------
- AddArg("Test_Abort=on");
-
- // --------------------------------
- // pause for keypress on exit (In the Mac world? NOT!)
- // --------------------------------
- AddArg("Pause_When_Done=off");
-
- // --------------------------------
- // Min Language Syntax Version
- // --------------------------------
- if ((**gPrefs2Use_h).languageVersion < eMaxLangVersion)
- {
- sprintf(s1, "Version=%d", (int)(**gPrefs2Use_h).languageVersion);
- AddArg(s1);
- }
-
- // --------------------------------
- // rendering Quality value
- // --------------------------------
- sprintf(s1, "Quality=%d", (**gPrefs2Use_h).renderQuality);
- AddArg(s1);
-
- // --------------------------------
- // radiosity Quality flag
- // --------------------------------
- if ((**gPrefs2Use_h).radQuality > 0)
- AddArg("Radiosity=on");
-
- // --------------------------------
- // set clock variable value
- // --------------------------------
- if ((**gPrefs2Use_h).doAnimation)
- {
- sprintf(s1, "Clock=%g", GetCurrClockVal());
- AddArg(s1);
- }
-
- // --------------------------------
- // set histogram info
- // --------------------------------
- if ((**gPrefs2Use_h).doHistogram)
- {
- sprintf(s1, "Histogram_Type=%c", (**gPrefs2Use_h).histogramType);
- AddArg(s1);
-
- // Put raw file name into histogram output filename
- strcpy((char*)s2, rawFileName);
-
- // get file type suffix (targa or ppm)
- switch ((**gPrefs2Use_h).histogramType)
- {
- case eOutfTarga: // uncompressed targa
- AddArg("Histogram_Type=T");
- strcpy(s2, ".tga");
- break;
- case eOutfTargaC: // compressed targa
- AddArg("Histogram_Type=C");
- strcpy(s2, ".tga");
- break;
- case eOutfPNG: // PNG
- AddArg("Histogram_Type=N");
- strcpy(s2, "png");
- break;
- case eOutfPPM: // Unix ppm file
- AddArg("Histogram_Type=P");
- strcpy(s2, "ppm");
- break;
- case eOutfNone:
- default:
- AddArg("Histogram_Type=T");
- strcpy(s2, "tga");
- break;
- }
-
- sprintf(s1, "Histogram_Grid_Size=%d.%d",
- (**gPrefs2Use_h).histogramXSize,
- (**gPrefs2Use_h).histogramYSize);
- AddArg(s1);
- sprintf(s1, "Histogram_File=%s.hist.%s", rawFileName, s2); // WARNING: This fname could be to long!
- AddArg(s1);
- }
-
- // --------------------------------
- // show render progress messages
- // --------------------------------
- switch ((**gPrefs2Use_h).progress)
- {
- case eProgDebug: // used by Mac only
- // fall through to set verbose ON as well
-
- case eProgVerbose:
- AddArg("Verbose=on");
- break;
-
- case eProgNone:
- case eProgMac:
- // Minimal is Mac debugs, not core debugs, and the Mac code
- // will show its debugs when eProgMac is on.
- AddArg("Verbose=off");
- break;
- }
-
- // --------------------------------
- // render output size
- // --------------------------------
- sprintf(s1, "Width=%d", (**gPrefs2Use_h).imageWidth);
- AddArg(s1);
-
- sprintf(s1, "Height=%d", (**gPrefs2Use_h).imageHeight);
- AddArg(s1);
-
- // --------------------------------
- // actual render rectangle
- // --------------------------------
- if ((**gPrefs2Use_h).selectionArea.top > 1)
- {
- sprintf(s1, "Start_Row=%d", (**gPrefs2Use_h).selectionArea.top);
- AddArg(s1);
- }
-
- sprintf(s1, "End_Row=%d", (**gPrefs2Use_h).selectionArea.bottom);
- AddArg(s1);
-
- if ((**gPrefs2Use_h).selectionArea.left > 1)
- {
- sprintf(s1, "Start_Column=%d", (**gPrefs2Use_h).selectionArea.left);
- AddArg(s1);
- }
-
- sprintf(s1, "End_Column=%d", (**gPrefs2Use_h).selectionArea.right);
- AddArg(s1);
-
- // --------------------------------
- // anti-aliasing
- // --------------------------------
- if ((**gPrefs2Use_h).doAntialias)
- {
- AddArg("Antialias=on");
- sprintf(s1, "Antialias_Threshold=%g", (**gPrefs2Use_h).antialiasThreshold);
- AddArg(s1);
-
-
- // Anti-aliasing Sampling method (1 or 2)
- sprintf(s1, "Sampling_Method=%d", (**gPrefs2Use_h).antialiasMethod);
- AddArg(s1);
-
- // Anti-aliasing Depth
- sprintf(s1, "Antialias_Depth=%d", (**gPrefs2Use_h).antialiasDepth);
- AddArg(s1);
-
- // Anti-aliasing Jitter Scale
- sprintf(s1, "Jitter_Amount=%g", (**gPrefs2Use_h).antiJitterScale);
- AddArg(s1);
- }
- else
- AddArg("Antialias=off");
-
- // --------------------------------
- // Mosaic preview mode
- // --------------------------------
- if ((**gPrefs2Use_h).previewStart > 0)
- {
- sprintf(s1, "Preview_Start_Size=%d", 1<<((**gPrefs2Use_h).previewStart-1));
- AddArg(s1);
- sprintf(s1, "Preview_End_Size=%d", 1<<((**gPrefs2Use_h).previewEnd-1));
- AddArg(s1);
- }
-
- // --------------------------------
- // enable/disable bounding slabs
- // --------------------------------
- if ((**gPrefs2Use_h).doBoundSlabs)
- {
- // set min objects to start auto-bounding
- sprintf(s1, "Bounding_Threshold=%d", (**gPrefs2Use_h).boundSlabThreshold);
- AddArg(s1);
- }
-
- // --------------------------------
- // enable/disable field rendering
- // --------------------------------
- if ((**gPrefs2Use_h).doFieldRender)
- {
- // set min objects to start auto-bounding
- AddArg("Field_Render=on");
- // set which scanline to start on
- if ((**gPrefs2Use_h).doOddField)
- AddArg("Odd_Field=on");
- else
- AddArg("Odd_Field=off");
- }
- else
- AddArg("Field_Render=off");
-
- // --------------------------------
- // Split unions
- // --------------------------------
- sprintf(s1, "Split_Unions=%d", (**gPrefs2Use_h).doSplitUnions); // on/off
- AddArg(s1);
-
- // --------------------------------
- // Vista/Light Buffers
- // --------------------------------
- sprintf(s1, "Vista_Buffer=%d", (**gPrefs2Use_h).doVistaBuffer); // on/off
- AddArg(s1);
-
- sprintf(s1, "Light_Buffer=%d", (**gPrefs2Use_h).doLightBuffer); // on/off
- AddArg(s1);
-
- sprintf(s1, "Draw_Vistas=%d", (**gPrefs2Use_h).doVistaDraw); // on/off
- AddArg(s1);
-
- sprintf(s1, "Remove_Bounds=%d", (**gPrefs2Use_h).removeBounds); // on/off
- AddArg(s1);
-
- // --------------------------------
- // continue with previous targa file
- // --------------------------------
- sprintf(s1, "Continue_Trace=%d", (**gPrefs2Use_h).continueTarga); // on/off
- AddArg(s1);
-
- // --------------------------------
- // Output buffer size
- // --------------------------------
- if ((**gPrefs2Use_h).outfileBuffSize)
- {
- sprintf(s1, "Buffer_Size=%d", (**gPrefs2Use_h).outfileBuffSize); // in KBytes
- AddArg(s1);
- }
-
- // --------------------------------
- // Add +L options for library paths
- // convert volume name to vref for making full path
- // --------------------------------
- VolName2VRef((**gAppPrefs_h).includeDirFSSpec.name,
- &(**gAppPrefs_h).includeDirFSSpec.vRefNum);
- PathNameFromDirID((**gAppPrefs_h).includeDirFSSpec.parID, (**gAppPrefs_h).includeDirFSSpec.vRefNum, s2);
- // whack trailing colon, POV-Ray wants to add it!
- if (s2[strlen(s2)-1] == ':')
- s2[strlen(s2)-1] = '\0';
- sprintf(s1, "Library_Path=%s", s2);
- AddArg(s1);
-
- // --------------------------------
- // Create INI output file
- // --------------------------------
- if ((**gPrefs2Use_h).doCreateINI)
- {
- sprintf(s1, "Create_Ini=%s.ini", rawFileName);
- AddArg(s1);
- }
-
- // --------------------------------
- // Is there a file-specific INI file to read in?
- // --------------------------------
-
- // If there is an INI file in this folder with the scene file, tell POV to read it
- sprintf(s2, "%s.ini", rawFileName);
- if (File_Exists(s2))
- {
- sprintf(s1, "Include_Ini=%s", s2);
- AddArg(s1);
- }
-
- // --------------------------------
- // Clean up
- // --------------------------------
-
- // flush any pending writes prior to rendering
- FlushVol(NULL, gSrcWind_VRefNum);
-
- Stop_Flag = 0;
- gDoingRender = true;
-
- // All done with temporary string buffers
- if (s1)
- DisposePtr((Ptr)s1);
- if (s2)
- DisposePtr((Ptr)s2);
-
- // calculate current CPU timeslice setting
- CalcCpuReleaseTicks(true);
-
- } // SetupRenderArgs
-
-
-
- // ---------------------------------------------------------------------
- // Set all menu items availability depending on application states
- static void SetItemEnable(MenuHandle theMenu, short theItem, Boolean isEnabled)
- {
- if (isEnabled)
- EnableItem(theMenu, theItem);
- else
- DisableItem(theMenu, theItem);
- } // SetItemEnable
-
-
-
-
- // ---------------------------------------------------------------------
- // Prompt user "OK to Quit?"
- static void ask_about_quit(void)
- {
- short itemHit;
-
- if ( gDoingRender &&
- ( ((**gPrefs2Use_h).outfileType == eOutfTarga)
- || ((**gPrefs2Use_h).outfileType == eOutfTargaC)
- || ((**gPrefs2Use_h).outfileType == eOutfPNG) )
- )
- {
- // ok to quit?
- itemHit = DisplayModalDialog(137, ok, cancel, NULL, 0, ewcDoCentering, eSameAsPassedWindow);
- if (itemHit == ok)
- {
- Stop_Flag = true;
- SetAppQuit();
- }
- }
- else
- {
- Stop_Flag = true;
- SetAppQuit();
- }
- } // ask_about_quit
-
-
-
- // ---------------------------------------------------------------------
- // Prompt user, "OK to Stop Rendering?"
- static void ask_about_stop(void)
- {
- short itemHit;
-
- if ( ((**gPrefs2Use_h).outfileType == eOutfTarga)
- || ((**gPrefs2Use_h).outfileType == eOutfTargaC)
- || ((**gPrefs2Use_h).outfileType == eOutfPNG))
- // stopped, to continue, use targa/png..
- itemHit = DisplayModalDialog(135, ok, 0, NULL, 0, ewcDoCentering, eSameAsPassedWindow);
- else
- // no targa, OK to stop?
- itemHit = DisplayModalDialog(134, ok, cancel, NULL, 0, ewcDoCentering, eSameAsPassedWindow);
-
- if (itemHit == ok)
- {
- // For now, just set the STOP flag...
- Stop_Flag = 1;
- }
- } // ask_about_stop
-
-
-
- // ---------------------------------------------------------------------
- // Pause rendering until user continues
- static void pause_it(void)
- {
-
- if (gPaused == 1)
- gPaused = 2; // already recursively paused, so now un-pause
- else
- { // prepare to pause
- gPaused = 1;
- DisableMenus();
-
- // re-enable just the pause menu item
- EnableItem(myMenus[rnmn_ID - menu_offset], 0);
- EnableItem(myMenus[rnmn_ID - menu_offset], rnmn_pause);
- CheckItem(myMenus[rnmn_ID - menu_offset], rnmn_pause, 1);
- DrawMenuBar();
-
- // pause loop..
- do
- {
- // allow user to do stuff..
- Cooperate(true);
- // until they pick pause again (2)
- } while ((Stop_Flag == 0) && (gPaused != 2));
-
- // done pausing, restore & return
- EnableMenus();
- CheckItem(myMenus[rnmn_ID - menu_offset], rnmn_pause, 0);
- gPaused = 0;
- }
- } // pause_it
-
-
-
- // ---------------------------------------------------------------------
- // Handle any window's Activate event
- static void HandleActivate(WindowPtr theWindow, Boolean becomingActive)
- {
- if (becomingActive) // ACTIVATE
- {
- if (theWindow == gSrcWind_Window)
- {
- DoActivateEditor(becomingActive);
- }
- else if ((theWindow == (WindowPtr)gp2wWindow) && (gp2wWindow))
- {
- p2w_DoActivate(gp2wWindow, becomingActive);
- }
- else if (theWindow == gImageWindowPtr)
- {
- }
- }
- else // DE-ACTIVATE
- {
- if (theWindow == gSrcWind_Window)
- {
- DoActivateEditor(becomingActive);
- }
- else if ((theWindow == (WindowPtr)gp2wWindow) && (gp2wWindow))
- {
- p2w_DoActivate(gp2wWindow, becomingActive);
- }
- else if (theWindow == gImageWindowPtr)
- {
- }
- }
- } // HandleActivate
-
-
-
-
- // ---------------------------------------------------------------------
- // Display additional credits on POV-Ray startup
- void PrintMacCredits(void)
- {
- char appVers[32];
-
- GetAppVersionPString(1, (StringPtr)appVers);
- p2cstr((StringPtr)appVers);
- fprintf (stderr,"\n");
- fprintf (stderr,"POV-Ray version %s [%s]\n\n", appVers,COMPILER_VER);
-
- fprintf (stderr,"This Macintosh implementation of POV-Ray is brought to you by:\n");
- fprintf (stderr," Eduard Schwan\n");
-
- fprintf (stderr,"Version 3.0.2 Editor 'undo' support code by:\n");
- fprintf (stderr," Thorsten Froehlich, CIS 106325,3677\n");
-
- fprintf (stderr,"Past Macintosh development help:\n");
- fprintf (stderr," David Harr Jim Nitchals\n");
-
- #if defined(powerc) || defined (__powerc)
- fprintf (stderr,"Past Power Macintosh development guidance:\n");
- fprintf (stderr," David Harr Paul Snively Monroe Williams\n");
- #endif
-
- fprintf (stderr,"----------------------------------------------------------------------\n\n");
- } // PrintMacCredits
-
-
-
- // ---------------------------------------------------------------------
- // Moves and sizes the window passed to fit the Rect passed.
- // No checking is done to see that it fits on a screen.
- static void MoveSizeWindow(WindowPtr pWindow, Rect * pWindRect)
- {
- // position & size the window
- MoveWindow(pWindow, pWindRect->left, pWindRect->top, false);
- // oh the grodiest hack for now... someday, all windows will be equal!
- // until then, we gotta put up with the skanky editor window.
- if (pWindow == gSrcWind_Window)
- MyResizeWindow(pWindow, pWindRect->right - pWindRect->left, pWindRect->bottom - pWindRect->top);
- else
- SizeWindow(pWindow, pWindRect->right - pWindRect->left, pWindRect->bottom - pWindRect->top, false);
- } // MoveSizeWindow
-
-
- // ---------------------------------------------------------------------
- // positions and displays a new source window.
- static void OpenNewSourceWindow(void)
- {
- // set up window title to be file name
- SetWTitle(gSrcWind_Window, gSrcWind_FileName);
-
- // Set Image window to saved position, shown later when render starts
- MoveSizeWindow(gImageWindowPtr, &(**gFilePrefs_h).imageWind_pos);
-
- // Set Source window position to saved position & show it
- MoveSizeWindow(gSrcWind_Window, &(**gFilePrefs_h).srcWind_pos);
-
- // Make sure it is visible
- ShowWindow(gSrcWind_Window);
- // reset the selection to beginning of file
- // It would be nice to remember users last selection/insertion point & restore it here...
- // but I'd like to use the MPW/BBEdit 'MPSR' resource for this (as well as window pos.)
- SrcWindSetSelect(0, 0);
- // force editor to scroll to selection
- ShowSelect();
- // pull new source window to front... but...
- SelectWindow(gSrcWind_Window);
- // open up behind other windows if splash screen or MModal dialog is up
- if (SplashScreenShown())
- SelectSplashScreen(); // pull splash screen back to front
- else if (IsMModalDialogDisplayed())
- SelectWindow(GetCurrMModalDialog()); // pull modal to front
-
- gSrcWind_visible = TRUE;
- } // OpenNewSourceWindow
-
-
- // ---------------------------------------------------------------------
- // Convert a vref/dirID into a magic vref (working dir)
- static OSErr MyDirID2VrefNum(short vRefNum, long dirID, short *theWDVrefNumPtr)
- {
- OSErr anError;
-
- // Open a Working directory for ourselves. Note that we leave
- // it open forever (just like SFGetFile does.) This is supposed
- // to be kosher, the Finder is to clean up after us when we quit!?
- anError = OpenWD(vRefNum, dirID, kAppSignature, theWDVrefNumPtr);
- return anError;
- } // MyDirID2VrefNum
-
-
-
- // ---------------------------------------------------------------------
- // General entry to open a source file for editing
- void OpenTextFile(Str255 fn, short vRef, long dirID, Boolean UseDirID)
- {
- short fRefNum, vRefNum;
- int errcode = noErr;
-
- // close any existing file first
- CloseMyWindow();
-
- // If ODOC, find working dir from vref/dirID so we can use FSOpen etc.
- if (UseDirID)
- {
- // convert vref/dirID into WD vrefnum for later FSOpen and SetVol calls
- errcode = MyDirID2VrefNum(vRef, dirID, &vRefNum);
- }
- else
- {
- vRefNum = vRef;
- }
-
- if (errcode==noErr)
- errcode = FSOpen(fn, vRefNum, &fRefNum);
- if (errcode==noErr)
- {
- gSrcWind_dirty = FALSE; // may turn ON in ReadFile
- errcode = ReadFile(fRefNum);
- FSClose(fRefNum); /* and ignore close errors */
- if (errcode == noErr)
- {
- pStrCopy(fn, gSrcWind_FileName);
- gSrcWind_VRefNum = vRefNum;
- FilePrefs_Read(gSrcWind_VRefNum, gSrcWind_FileName);
- OpenNewSourceWindow();
- }
- else if (errcode == 999)
- FileError("\pFile too large to be edited: ", fn);
- else
- FileError("\pError reading ", fn);
- }
- else
- FileError("\pError opening ", fn);
-
- } // OpenTextFile
-
-
-
- // ---------------------------------------------------------------------
- // Save the status window text into a new text file
- static int Save_StatusWindow(void)
- {
- OSErr ioError;
- char hstate;
- short vRef = 0;
- short refNum;
- char fn[] = "\pPOV-Ray Status.Window";
-
- ShowWatchCursor(); // could take a little while..
-
- ioError = FSDelete((StringPtr)fn, vRef);
- ioError = Create((StringPtr)fn, vRef, 'ttxt', 'TEXT');
- if ((ioError == noErr) || (ioError == dupFNErr))
- ioError = FSOpen((StringPtr)fn, vRef, &refNum);
- if (ioError)
- {
- ShowArrowCursor(); // all done
- FileError("\pError creating Status file ", (StringPtr)fn);
- return (0);
- }
- else
- {
- hstate = HGetState((**gp2wWindow->p2wTEHandle).hText);
- HLock((**gp2wWindow->p2wTEHandle).hText);
-
- if (WriteFile(refNum, (*(**gp2wWindow->p2wTEHandle).hText),
- (long)(**gp2wWindow->p2wTEHandle).teLength))
- FileError("\pError writing file ", (StringPtr)fn);
-
- HSetState((**gp2wWindow->p2wTEHandle).hText, hstate);
-
- FSClose(refNum);
-
- ShowArrowCursor(); // all done
- return(1);
- }
- } // Save_StatusWindow
-
-
-
- // ---------------------------------------------------------------------
- // Done rendering, beep or auto-shutdown if requested
- static void notify_user(void)
- {
- Boolean doFeedback = false;
- Boolean doBeep = false;
- Boolean doDialog = false;
- Boolean doQuit = false;
- Boolean doShutdown = false;
-
- if (gRenderedOK)
- SetCustomPalette(!gInBackground);
-
- /* If the image rendered OK and shutdown was requested, then shut down. */
- if (gRenderedOK)
- {
- switch (APGet_AllDoneNotify())
- {
- case eDone_Quiet: // don't notify at all when done
- break;
- case eDone_Beep: // do noise
- doBeep = true;
- break;
- case eDone_Dialog: // do dialog
- doDialog = true;
- break;
- case eDone_BnD: // do noise & dialog
- doBeep = true;
- doDialog = true;
- break;
- case eDone_Quit: // quit app
- doQuit = true;
- break;
- } // switch
-
- // check for shutting down when done
- if (APGet_ShutDownWhenDone())
- {
- doQuit = true;
- doShutdown = true;
- }
- }
-
- // Set our quit flag
- if (doQuit)
- {
- Save_StatusWindow();
- SetAppQuit();
- }
-
- // get everyone's attention...
- if (doBeep)
- PlayNotifySound();
- if (doDialog)
- ShowNotifyDialog();
- if (doShutdown)
- DoShutdownMac();
-
- } // notify_user
-
-
-
- // ---------------------------------------------------------------------
- // create and display a new empty source window
- void DoFile_New(void)
- {
- // close any existing file
- CloseMyWindow();
-
- // set up untitled
- SetUpFiles();
-
- // new file gets default prefs
- **gFilePrefs_h = **gDefltFilePrefs_h;
-
- OpenNewSourceWindow();
- gSrcWind_dirty = FALSE;
-
- } // DoFile_New
-
-
-
- // ---------------------------------------------------------------------
- // Prompt user for a source file, and open it into source window
- void DoFile_Open(void)
- {
- short vRef = 0;
- Str255 fn;
-
- if (OldFile(fn, &vRef))
- {
- OpenTextFile(fn, vRef, 0L, false/*!UseDirID*/);
- }
- } // DoFile_Open
-
-
-
- // ---------------------------------------------------------------------
- // Set up, call the renderer, and notify user when done
- static void DoRendering(void)
- {
- Boolean stillDoingAnimation;
- long start_ticks;
- short animFrameNumber;
-
- if (gSrcWind_dirty)
- if (DoFile(fmn_save))
- ;
-
- gInAnimationLoop = (**gPrefs2Use_h).doAnimation;
- gAnimRec = (**gPrefs2Use_h).animRec;
- SetCurrFrameVal(&gAnimRec, gAnimRec.frameValS);
- stillDoingAnimation = gInAnimationLoop;
- gAutoShutdown = APGet_ShutDownWhenDone();
-
-
- // pull status window to front (not user-friendly, but user-requested!)
- SelectWindow((WindowPtr)gp2wWindow);
-
- do {
- // init the fake argc/argv buffers
- InitArgv();
-
- SetupRenderArgs();
-
- if ( stillDoingAnimation && ((**gPrefs2Use_h).progress >= eProgMac) )
- {
- printf("-- [Animation] StartFrame=%d, EndFrame=%d, CurrFrame=%d, CurrClock=%g)\n",
- gAnimRec.frameValS, gAnimRec.frameValE, GetCurrFrameVal(), GetCurrClockVal());
- }
-
- start_ticks = MAC_TICKS;
-
- // Do the real POV-Ray work now
- if (!Stop_Flag && !AppIsQuitting())
- call_main(my_argc, my_argv);
-
- // all done with the argc/argv buffers
- DestroyArgv();
-
- // write PICT file with current name.PICT
- if (
- (APGet_AutoSaveImage() || gAutoShutdown
- || gInAnimationLoop || gDoingBatchODOCs)
- && gRenderedOK && !Stop_Flag && !AppIsQuitting()
- )
- {
- // set up frame # suffix (if any)
- if (gInAnimationLoop)
- animFrameNumber = GetCurrFrameVal();
- else
- animFrameNumber = kNoAnimSuffix;
- // save the image
- SaveOutputFile(false, gtheSCComponent);
- }
-
- // next frame
- if (gInAnimationLoop)
- stillDoingAnimation = IncToNextFrame(&gAnimRec);
-
- } while (stillDoingAnimation && !Stop_Flag && !AppIsQuitting());
-
- gInAnimationLoop = false;
-
- /*
- If POV wasn't prematurely stopped, and if it is not in the middle of
- multiple renders, then call the notification procedure.
- */
- if (!Stop_Flag && (FileQ_NumItems() == 0))
- notify_user();
-
- gBeginRendering = false; // all done for now
- gDoingBatchODOCs = false; // in case it was on from odoc
-
- if (APGet_AllDoneNotify() == eDone_Quit)
- SetAppQuit();
- } // DoRendering
-
-
-
-
- // ---------------------------------------------------------------------
- // Open a source file, render it, save the image PICT, and close the source file
- static void BatchProcessOneFile(FSSpec *pFile)
- {
- gDoingBatchODOCs = true; // postpone other ODOCs until done with this one!
-
- OpenTextFile(pFile->name, pFile->vRefNum, pFile->parID, true/*UseDirID*/);
- DoRendering();
- DoFile(fmn_close);
-
- gDoingBatchODOCs = false;
- } // BatchProcessOneFile
-
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Apple menu
- static void DoAppleMenu(short theItem)
- {
- Str255 name;
-
- if (theItem == apmn_about)
- DoAboutBox();
- else
- {
- GetMenuItemText(myMenus[apmn_ID - menu_offset], theItem, name);
- OpenDeskAcc(name);
- }
- } // DoAppleMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the File menu
- static void DoFileMenu(short theItem)
- {
- WindowPtr theFrontWindow;
-
- theFrontWindow = FrontWindow();
- switch (theItem)
- {
- case fmn_new: /* New File */
- DoFile_New();
- break;
-
- case fmn_open: /* Open a file */
- DoFile_Open();
- break;
-
- case fmn_close: /* Close */
- if (theFrontWindow == gImageWindowPtr)
- CloseImageWindow();
- else if (theFrontWindow == gSrcWind_Window)
- DoFile(fmn_close);
- break;
-
- case fmn_save: /* Save */
- if (theFrontWindow == gSrcWind_Window)
- {
- DoFile(fmn_save);
- }
- else if (theFrontWindow == gImageWindowPtr)
- SaveOutputFile(false, gtheSCComponent); // don't prompt for name
- else if (theFrontWindow == (WindowPtr)gp2wWindow)
- Save_StatusWindow();
- break;
-
- case fmn_saveas: /* Save as… */
- if (theFrontWindow == gSrcWind_Window)
- {
- DoFile(fmn_saveas);
- }
- else if (theFrontWindow == gImageWindowPtr)
- SaveOutputFile(true, gtheSCComponent); // prompt for name
- else if (theFrontWindow == (WindowPtr)gp2wWindow)
- Save_StatusWindow();
- break;
-
- case fmn_revert: /* Revert to saved */
- if (theFrontWindow == gSrcWind_Window)
- {
- DoFile(fmn_revert);
- }
- break;
-
- case fmn_quit:
- ask_about_quit();
- // if user still wanted to quit, try to close editor file
- if (AppIsQuitting())
- if (DoFile(fmn_close))
- ;
- break; /* Quit the program */
- }
- } // DoFileMenu
-
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Edit menu
- static void DoEditMenu(short theItem)
- {
- WindowPtr theFrontWindow;
-
- theFrontWindow = FrontWindow();
-
- if (SystemEdit(theItem-1) != 0)
- return;
-
- /* handle the menu items for the front window */
- switch (theItem)
- {
- case edmn_undo: /*undo*/
- if (theFrontWindow == gSrcWind_Window)
- {
- SrcWindUndo();
- }
- else if (theFrontWindow == gImageWindowPtr)
- {
- }
- break;
-
- case edmn_redo: /*redo*/
- if (theFrontWindow == gSrcWind_Window)
- {
- SrcWindRedo();
- }
- else if (theFrontWindow == gImageWindowPtr)
- {
- }
- break;
-
- case edmn_cut:
- if (theFrontWindow == gSrcWind_Window)
- {
- SrcWindCutSelToClipboard();
- gSrcWind_dirty = 1;
- }
- break;
-
- case edmn_copy: /*copy*/
- if (theFrontWindow == gSrcWind_Window)
- {
- SrcWindCopySelToClipboard();
- }
- else if (theFrontWindow == gImageWindowPtr)
- {
- ZeroScrap(); // clear out the clipboard
- paint_to_picture(false);
- TEToScrap(); // export
- }
- else if (theFrontWindow == (WindowPtr)gp2wWindow)
- {
- ZeroScrap(); // clear out the clipboard
- TECopy(gp2wWindow->p2wTEHandle);
- TEToScrap(); // export
- }
- break;
-
- case edmn_paste:
- if (theFrontWindow == gSrcWind_Window)
- {
- SrcWindPasteFromClipboard();
- gSrcWind_dirty = 1;
- }
- break;
-
- case edmn_clear:
- if (theFrontWindow == gSrcWind_Window)
- {
- SrcWindClearSel();
- gSrcWind_dirty = 1;
- }
- break;
-
- case edmn_selectAll:
- if (theFrontWindow == gSrcWind_Window)
- {
- SelectAllText();
- }
- else if (theFrontWindow == (WindowPtr)gp2wWindow)
- {
- p2w_SelectAll(gp2wWindow);
- }
- break;
-
- case edmn_goto:
- choose_goto_line();
- break;
-
- case edmn_matchbrace:
- MatchBracesAtCurSel();
- break;
- } /*switch*/
- } // DoEditMenu
-
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Template menu
- static void DoTemplateMenu(short theMenu, short theItem)
- {
- switch(theItem)
- {
- case temn_import:
- ImportTemplates();
- break;
- default:
- HandleTemplateMenu(theMenu, theItem);
- break;
- }
- } // DoTemplateMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Image menu
- static void DoImageMenu(short theItem)
- {
- if (theItem == immn_dither)
- {
- // toggle it
- (**gPrefs2Use_h).doDither = !(**gFilePrefs_h).doDither;
- // make sure file prefs are updated too (in case using app prefs)
- (**gFilePrefs_h).doDither = (**gPrefs2Use_h).doDither;
- InvalRect_ImageWindow(false);
- }
- } // DoImageMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the View menu
- static void DoViewMenu(short theItem)
- {
- // Set the file prefs
- (**gPrefs2Use_h).imageMagFactor = theItem;
- SetImageWindowMag(theItem);
- } // DoViewMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Image menu
- static void DoPaletteMenu(short theItem)
- {
- switch(theItem)
- {
- case palette_none:
- gUsingCustomPalette = false;
- gColorQuantMethod = -1;
- break;
-
- case palette_default:
- gUsingCustomPalette = true;
- gColorQuantMethod = systemMethod;
- break;
-
- case palette_median:
- gUsingCustomPalette = true;
- gColorQuantMethod = medianMethod;
- break;
-
- case palette_popular:
- gUsingCustomPalette = true;
- gColorQuantMethod = popularMethod;
- break;
-
- case palette_var_min:
- gUsingCustomPalette = true;
- gColorQuantMethod = varianceMethod;
- break;
-
- case palette_octree:
- gUsingCustomPalette = true;
- gColorQuantMethod = octreeMethod;
- break;
- }
-
- if (((WindowPeek)gImageWindowPtr)->visible)
- SetCustomPalette(!gInBackground);
- } // DoPaletteMenu
-
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Image menu
- static void DoPrefsMenu(short theItem)
- {
- switch(theItem)
- {
- case pref_app:
- DisableMenus();
- AppPrefs_Prompt_Init(); // mmodal
- break;
-
- case pref_file:
- if (gSrcWind_dirty)
- if (DoFile(fmn_save)) ;
- DisableMenus(); // re-enabled when ok/cancel pressed
- FilePrefs_Prompt_Init(gSrcWind_VRefNum, gSrcWind_FileName); // mmodal
- break;
- }
- } // DoPrefsMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Render menu
- static void DoRenderMenu(short theItem)
- {
- switch(theItem)
- {
- case rnmn_render: /* Render */
- if (gSrcWind_dirty)
- if (DoFile(fmn_save))
- ;
- gBeginRendering = true;
- break;
-
- case rnmn_pause: /* pause trace */
- pause_it();
- break;
-
- case rnmn_stop: /* Abort trace in progress? */
- ask_about_stop();
- break;
- }
- } // DoRenderMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Processing menu
- #ifdef XXX
- static void DoPPMenu(short theItem)
- {
- switch (theItem)
- {
- case psmn_border:
- draw_border();
- break;
-
- case psmn_darken:
- darken_image();
- break;
-
- case psmn_lighten:
- lighten_image();
- break;
-
- case psmn_reduceC:
- reduce_contrast();
- break;
-
- case psmn_increaseC:
- increase_contrast();
- break;
-
- case psmn_invert:
- invert_image();
- break;
-
- case psmn_revert:
- revert_image();
- break;
- }
- } // DoPPMenu
- #endif
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from the Windows menu
- static void DoWindMenu(short theItem)
- {
- switch (theItem)
- {
- case wndmn_status:
- if (gp2wWindow)
- {
- SelectWindow((WindowPtr)gp2wWindow);
- }
- break;
-
- case wndmn_source:
- if ((gSrcWind_Window) && (gSrcWind_visible))
- {
- SelectWindow(gSrcWind_Window);
- }
- break;
-
- case wndmn_image:
- if (((WindowPeek)gImageWindowPtr)->visible)
- {
- SelectWindow(gImageWindowPtr);
- }
- break;
-
- case wndmn_autoscroll:
- if (gp2wWindow)
- {
- // flip its state
- p2w_AlwaysScrollToBottom(gp2wWindow, !p2w_AlwaysScrollToBottomState(gp2wWindow));
- // if we are now auto-scrolling, force it to the bottom immediately
- if (p2w_AlwaysScrollToBottomState(gp2wWindow))
- p2w_ScrollEnd(gp2wWindow);
- }
- break;
- }
- } // DoWindMenu
-
-
- // ---------------------------------------------------------------------
- // Handle choosing items from various menus
- static void DoMenuCommand(long m)
- {
- short theMenu, theItem;
-
- theMenu = (m >> 16);
- theItem = m;
- switch (theMenu)
- {
- case apmn_ID: /* Apple Menu */
- DoAppleMenu(theItem);
- break;
-
- case fmn_ID: /* File Menu */
- DoFileMenu(theItem);
- break;
-
- case edmn_ID: /* Edit Menu */
- DoEditMenu(theItem);
- break;
-
- case temn_ID: /* Template Menu */
- DoTemplateMenu(theMenu, theItem);
- break;
-
- case immn_ID: /* Image Menu */
- DoImageMenu(theItem);
- break;
-
- case viewmn_ID: /* View submenu */
- DoViewMenu(theItem);
- break;
-
- case plmn_ID: /* Custom Palette submenu */
- DoPaletteMenu(theItem);
- break;
-
- case pfmn_ID: /* Prefs submenu */
- DoPrefsMenu(theItem);
- break;
-
- case rnmn_ID: /* Render Menu */
- DoRenderMenu(theItem);
- break;
-
- case wndmn_ID: /* Windows menu */
- DoWindMenu(theItem);
- break;
-
- case kHMHelpMenuID: /* Defined in Balloons.h */
- // if we decide to add help in our own Help menu...
- break;
-
- default:
- // If it is none of the above, it may be one of the dynamically added
- // template menus...
- HandleTemplateMenu(theMenu, theItem);
- break;
- }
-
- HiliteMenu(0);
-
- } // DoMenuCommand
-
-
-
- // ---------------------------------------------------------------------
- // Set all menu items availability depending on application states
- static void AdjustMenus(void)
- {
- short i;
- Boolean inLowMemMode;
- WindowPtr theFrontWindow;
-
- // Find out which window is in front, many menus depend on which is frontmost.
- theFrontWindow = FrontWindow();
- inLowMemMode = InLowMemoryMode();
-
- #ifdef DO_BETA
- // if we timed out, pretend we're rendering...
- // this will force the important menus OFF so they cannot be accessed.
- // this tricky way of doing things is simply to slow down MacNosy's out there...
- if (gTimeoutFlag > 0.0)
- gDoingRender = (gTimeoutFlag > 0.0);
- #endif // DO_BETA
-
- //======== APPLE
-
- SetItemEnable(myMenus[apmn_ID - menu_offset], apmn_about, !inLowMemMode && !gDoingRender); /* about box */
-
-
- //======== FILE
-
- // disable whole menu if dialog is up
- SetItemEnable(myMenus[fmn_ID - menu_offset], 0, !IsMModalDialogDisplayed());
-
- // ---- New
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_new, !gDoingRender && !gSrcWind_dirty && !inLowMemMode);
-
- // ---- Open
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_open, !gDoingRender && !gSrcWind_dirty && !inLowMemMode);
-
- // ---- Close
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_close, false);
- if (theFrontWindow == gSrcWind_Window)
- {
- if (!gDoingRender)
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_close, true);
- }
- /* -- not yet, need to prompt to save first
- else if (theFrontWindow == gImageWindowPtr)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_close, true);
- }
- */
-
- // ---- Save
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_save, gSrcWind_dirty || (gSrcWind_VRefNum == 0));
- }
- else if (theFrontWindow == (WindowPtr)gp2wWindow)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_save, true);
- }
- else if (theFrontWindow == gImageWindowPtr)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_save, !gDoingRender && gImageWindIsValid);
- }
-
- // ---- Save As
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_saveas, true);
- }
- else if (theFrontWindow == gImageWindowPtr)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_saveas, !gDoingRender && gImageWindIsValid);
- }
- else
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_saveas, false);
- }
-
- // ---- Revert
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_revert, !gDoingRender && gSrcWind_dirty && (gSrcWind_VRefNum != 0));
- }
- else if (theFrontWindow == gImageWindowPtr)
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_revert, FALSE);
- }
- else
- {
- SetItemEnable(myMenus[fmn_ID - menu_offset], fmn_revert, FALSE);
- }
-
-
-
- //======== EDIT
-
- // ---- undo
- if (theFrontWindow == gSrcWind_Window)
- {
- gCanUndo = CheckSrcWindCanUndo();
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_undo, gCanUndo);
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_undo, false);
-
- // ---- cut
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_cut,
- GetSrcWindselStart() != GetSrcWindselEnd());
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_cut, false);
-
- // ---- copy
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_copy,
- GetSrcWindselStart() != GetSrcWindselEnd());
- }
- else
- if (theFrontWindow == gImageWindowPtr)
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_copy, !gDoingRender && gImageWindIsValid);
- }
- else
- if (theFrontWindow == (WindowPtr)gp2wWindow)
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset],
- edmn_copy,
- (**gp2wWindow->p2wTEHandle).selStart != (**gp2wWindow->p2wTEHandle).selEnd);
- }
-
- // ---- paste
- if (theFrontWindow == gSrcWind_Window)
- { // can only paste into src window
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_paste, true);
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_paste, false);
-
- // ---- clear
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_clear,
- GetSrcWindselStart() != GetSrcWindselEnd());
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_clear, false);
-
-
- // ---- select all
- if ((theFrontWindow == gSrcWind_Window) || (theFrontWindow == (WindowPtr)gp2wWindow))
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_selectAll, true);
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_selectAll, false);
-
- // ---- redo
- if (theFrontWindow == gSrcWind_Window)
- {
- gCanRedo = CheckSrcWindCanRedo();
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_redo, gCanRedo);
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_redo, false);
-
- // ---- goto
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_goto, gSrcWind_visible);
-
- // ---- match braces
- if (theFrontWindow == gSrcWind_Window)
- {
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_matchbrace, true);
- }
- else
- SetItemEnable(myMenus[edmn_ID - menu_offset], edmn_matchbrace, false);
-
-
-
- //======== TEMPLATE
-
- // disable whole menu if dialog is up
- SetItemEnable(myMenus[temn_ID - menu_offset], 0, !IsMModalDialogDisplayed());
-
- // ---- import file
- SetItemEnable(myMenus[temn_ID - menu_offset], temn_import, !TemplatesImported() && !inLowMemMode); // false when already read
-
-
- //======== IMAGE
-
- // disable whole menu if dialog is up
- SetItemEnable(myMenus[immn_ID - menu_offset], 0, !IsMModalDialogDisplayed());
-
- // ---- view
- SetItemEnable(myMenus[immn_ID - menu_offset], immn_view, true);
- // should disable view submenu if !gSrcWind_visible...
-
- // ---- dither
- SetItemEnable(myMenus[immn_ID - menu_offset], immn_dither, gHas32BitQD);
- CheckItem(myMenus[immn_ID - menu_offset], immn_dither, ((**gPrefs2Use_h).doDither && gHas32BitQD));
-
- // ---- custom palette
- SetItemEnable(myMenus[immn_ID - menu_offset], immn_custom, true);
-
-
- //======== RENDER
-
- // disable whole menu if dialog is up
- SetItemEnable(myMenus[rnmn_ID - menu_offset], 0, !IsMModalDialogDisplayed());
-
- // ---- render
- SetItemEnable(myMenus[rnmn_ID - menu_offset], rnmn_render,
- !gDoingRender && (gSrcWind_VRefNum != 0) && !inLowMemMode);
-
- // ---- pause rendering
- SetItemEnable(myMenus[rnmn_ID - menu_offset], rnmn_pause, gDoingRender);
-
- // ---- stop rendering
- SetItemEnable(myMenus[rnmn_ID - menu_offset], rnmn_stop, gDoingRender);
-
- //======== WINDOWS
-
- // disable whole menu if dialog is up
- SetItemEnable(myMenus[wndmn_ID - menu_offset], 0, !IsMModalDialogDisplayed());
-
- // ---- [1] status window
- CheckItem(myMenus[wndmn_ID - menu_offset], wndmn_status, theFrontWindow == (WindowPtr)gp2wWindow);
- SetItemEnable(myMenus[wndmn_ID - menu_offset], wndmn_status, gp2wWindow != NULL);
-
- // ---- [2] source window
- CheckItem(myMenus[wndmn_ID - menu_offset], wndmn_source, theFrontWindow == gSrcWind_Window);
- SetItemEnable(myMenus[wndmn_ID - menu_offset], wndmn_source, gSrcWind_visible);
-
- // ---- [3] image window
- CheckItem(myMenus[wndmn_ID - menu_offset], wndmn_image, theFrontWindow == gImageWindowPtr);
- SetItemEnable(myMenus[wndmn_ID - menu_offset], wndmn_image, gImageWindowPtr && ((WindowPeek)gImageWindowPtr)->visible);
-
- // ---- [4] Auto-scroll the status window
- CheckItem(myMenus[wndmn_ID - menu_offset], wndmn_autoscroll, p2w_AlwaysScrollToBottomState(gp2wWindow));
- SetItemEnable(myMenus[wndmn_ID - menu_offset], wndmn_autoscroll, gp2wWindow != NULL);
-
- //======== VIEW SUBMENU
-
- SetItemEnable(mySubMenus[viewmn_ID - submenu_offset], 0, true);
- for (i=viewmn_hidden; i <= viewmn_x4; i++)
- CheckItem(mySubMenus[viewmn_ID - submenu_offset], i, i == (**gPrefs2Use_h).imageMagFactor);
-
-
- //======== CUSTOM PALETTE SUBMENU
-
- for (i=palette_none; i <= palette_popular; i++)
- SetItemEnable(mySubMenus[plmn_ID - submenu_offset], i,
- gHasPictUtils && (i!=2) && (theFrontWindow == gImageWindowPtr) );
- CheckItem(mySubMenus[plmn_ID - submenu_offset], palette_none, !gUsingCustomPalette);
- CheckItem(mySubMenus[plmn_ID - submenu_offset], palette_default, gColorQuantMethod == systemMethod);
- CheckItem(mySubMenus[plmn_ID - submenu_offset], palette_median, gColorQuantMethod == medianMethod);
- CheckItem(mySubMenus[plmn_ID - submenu_offset], palette_popular, gColorQuantMethod == popularMethod);
-
- //======== File Prefs SUBMENU
-
- SetItemEnable(mySubMenus[pfmn_ID - submenu_offset], pref_file,
- !gDoingRender /* && (gSrcWind_VRefNum != 0) */ );
-
- } // AdjustMenus
-
-
-
- // ---------------------------------------------------------------------
- // Handle mouse down in windows or menus
- static void DoMouseDown(void)
- {
- short code;
- WindowPtr whichWindow;
- Rect theWindowPos;
-
- code = FindWindow(gTheEvent.where, &whichWindow);
-
- // don't allow window switch events
- if (whichWindow != FrontWindow() &&
- (code != inSysWindow) && (code != inMenuBar))
- {
- // if a dialog is up and we clicked outside it... beep & do nothing!
- if (IsMModalDialogDisplayed() && (whichWindow != GetCurrMModalDialog()))
- {
- SysBeep(4);
- return;
- }
- }
-
- if (whichWindow == gSrcWind_Window)
- {
- DoEditMouseDown (code, whichWindow, &gTheEvent);
- }
- else
- {
- switch (code)
- {
- case inMenuBar:
- ShowArrowCursor();
- AdjustMenus();
- DoMenuCommand(MenuSelect(gTheEvent.where));
- break;
-
- case inSysWindow:
- SystemClick(&gTheEvent, whichWindow);
- break;
-
- case inGoAway:
- // neither Image nor Status have a close box, and the
- // Source window's close is handled in DoEditMouseDown()
- if (TrackGoAway(whichWindow, gTheEvent.where))
- ;
- break;
-
- case inGrow:
- if ((whichWindow == (WindowPtr)gp2wWindow) && (gp2wWindow))
- { // Status Window
- p2w_DoGrow(gp2wWindow, &gTheEvent);
- GetGlobalWindowRect((WindowPtr)gp2wWindow, &theWindowPos);
- (**gFilePrefs_h).statWind_pos = theWindowPos;
- // also remember this as default for next time
- (**gDefltFilePrefs_h).statWind_pos = theWindowPos;
- }
- else if ((whichWindow == gImageWindowPtr) && (gImageWindowPtr))
- { // Image Window
- DoGrowImageWindow(gImageWindowPtr, gTheEvent.where);
- GetGlobalWindowRect(gImageWindowPtr, &theWindowPos);
- (**gFilePrefs_h).imageWind_pos = theWindowPos;
- // Uncomment the next line to keep updating the default
- // image wind position, not a good idea, IMHO.
- /*
- // also remember this as default for next time
- (**gDefltFilePrefs_h).imageWind_pos = theWindowPos;
- */
- }
- break;
-
- case inZoomIn:
- case inZoomOut:
- SelectWindow(whichWindow);
- if (TrackBox(whichWindow, gTheEvent.where, code))
- {
- if ((whichWindow == (WindowPtr)gp2wWindow) && (gp2wWindow))
- p2w_DoZoom(gp2wWindow, code);
- else if ((whichWindow == gImageWindowPtr) && (gImageWindowPtr))
- ; // none
- }
- break;
-
- case inDrag:
- if (whichWindow != FrontWindow())
- SelectWindow(whichWindow);
- else
- {
- DragWindow(whichWindow, gTheEvent.where, &gDragBounds);
- GetGlobalWindowRect(whichWindow, &theWindowPos);
- if ((whichWindow == (WindowPtr)gp2wWindow) && (gp2wWindow))
- { // Status window
- (**gFilePrefs_h).statWind_pos = theWindowPos;
- // also remember this as default for next time
- (**gDefltFilePrefs_h).statWind_pos = theWindowPos;
- }
- else if ((whichWindow == gImageWindowPtr) && (gImageWindowPtr))
- { // Image Window
- (**gFilePrefs_h).imageWind_pos = theWindowPos;
- // Uncomment the next line to keep updating the default
- // image wind position, not a good idea, IMHO.
- /*
- // also remember this as default for next time
- (**gDefltFilePrefs_h).imageWind_pos = theWindowPos;
- */
- }
- }
- break;
-
- case inContent:
- if (whichWindow != FrontWindow())
- SelectWindow(whichWindow);
- else
- {
- if ((whichWindow == (WindowPtr)gp2wWindow) && (gp2wWindow))
- p2w_DoContentClick(gp2wWindow, &gTheEvent);
- else if (whichWindow == gImageWindowPtr)
- {
- SetPort(whichWindow);
- GlobalToLocal(&gTheEvent.where);
- // perform marquee dragging in here!
- }
- }
- break;
- }
- }
- } // DoMouseDown
-
-
-
- // ---------------------------------------------------------------------
- // Handle key downs
- static void DoKeyDown(void)
- {
- char theChar, theVirtualCode;
-
- theChar = gTheEvent.message & charCodeMask;
- theVirtualCode = (gTheEvent.message & keyCodeMask) >> 8;
-
- if (gTheEvent.modifiers & cmdKey)
- {
- AdjustMenus();
- DoMenuCommand(MenuKey(theChar));
- }
- else
- {
- // Handle Status window
- if (FrontWindow() == (WindowPtr)gp2wWindow)
- p2w_DoKeyDown(gp2wWindow, theVirtualCode);
- // Handle Editor window
- else if (FrontWindow() == gSrcWind_Window)
- {
- switch (theVirtualCode)
- {
- case 0x33: // delete
- if (GetSrcWindselStart() != GetSrcWindselEnd())
- {
- SrcWindClearSel(); // delete selection
- gSrcWind_dirty = 1;
- }
- else
- { // if there is a left char!
- if(GetSrcWindselStart() > 0)
- {
- SrcWindTEDeleteLeftCharKey(); // delete char
- gSrcWind_dirty = 1;
- }
- }
- break;
-
- case 0x73: // HOME
- ScrollEditHome();
- break;
-
- case 0x77: // END
- ScrollEditEnd();
- break;
-
- case 0x74: // PAGE UP
- ScrollEditPage(kControlPageUpPart);
- break;
-
- case 0x79: // PAGE DOWN
- ScrollEditPage(kControlPageDownPart);
- break;
-
- case 0x7A: // UNDO (F1)
- SrcWindUndo();
- break;
-
- case 0x78: // CUT (F2)
- SrcWindCutSelToClipboard();
- gSrcWind_dirty = 1;
- break;
-
- case 0x63: // COPY (F3)
- SrcWindCopySelToClipboard();
- break;
-
- case 0x76: // PASTE (F4)
- SrcWindPasteFromClipboard();
- gSrcWind_dirty = 1;
- break;
-
- case 0x75: // forward-del |X>
- if (GetSrcWindselStart() != GetSrcWindselEnd())
- {
- SrcWindClearSel(); // delete selection
- gSrcWind_dirty = 1;
- }
- else
- { // if there is a right char!
- if((GetSrcWindteLength() - GetSrcWindselEnd()) > 0)
- {
- SrcWindTEDeleteRightCharKey(); // delete char
- gSrcWind_dirty = 1;
- }
- }
- break;
-
- /* Cursor keys, don't dirty the buffer or require undo */
- case 0x7B: // <- left
- case 0x3B:
-
- case 0x7C: // -> right
- case 0x3C:
-
- case 0x7D: // v down
- case 0x3D:
-
- case 0x7E: // ^ up
- case 0x3E:
- SrcWindTEKey(theChar);
- ShowSelect();
- break;
-
- default: // all other keys
- SrcWindTEKey(theChar);
- gSrcWind_dirty = 1;
- ShowSelect();
- }
- }
- }
- } // DoKeyDown
-
-
-
- // ---------------------------------------------------------------------
- // Handle disk inserted events (format uninit. disks if needed)
- static void DoDiskEvt(EventRecord * pTheEventPtr)
- {
- OSErr anError;
- Point aPoint;
-
- if (HiWord(pTheEventPtr->message) != noErr)
- { // prompt to format it
- GetBestDialogPos(&aPoint, (WindowPtr)gp2wWindow);
- anError = DIBadMount(aPoint, pTheEventPtr->message);
- }
- } // DoDiskEvt
-
-
-
- // ---------------------------------------------------------------------
- // Handle window update events
- static void DoUpdateEvt(void)
- {
- WindowPtr whichWindow;
-
- whichWindow = (WindowPtr) gTheEvent.message;
- if ((whichWindow == gSrcWind_Window) && gSrcWind_Window)
- UpdateWindow (whichWindow);
- else if ((whichWindow == (WindowPtr) gp2wWindow) && gp2wWindow)
- p2w_DoUpdate(gp2wWindow);
- else if ((whichWindow == gImageWindowPtr) && gImageWindowPtr)
- UpdateImageWindow();
- else if (IsMModalDialogDisplayed())
- if (whichWindow == GetCurrMModalDialog())
- {
- BeginUpdate(whichWindow);
- DrawDialog(whichWindow);
- EndUpdate(whichWindow);
- }
- } // DoUpdateEvt
-
-
-
- // ---------------------------------------------------------------------
- // Handle window activate events
- static void DoActivateEvt(void)
- {
- HandleActivate((WindowPtr) gTheEvent.message, gTheEvent.modifiers & 1);
- } // DoActivateEvt
-
-
-
- // ---------------------------------------------------------------------
- // Handle OS Events (Suspend/resume)
- static void DoOSEvt(void)
- {
- switch ((gTheEvent.message & osEvtMessageMask) >> 24) /* high byte of message */
- {
- case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (gTheEvent.message & resumeFlag) == 0;
- HandleActivate((WindowPtr) gTheEvent.message, gInBackground);
- break;
- }
- ShowArrowCursor();
-
- } // DoOSEvt
-
-
-
- // ---------------------------------------------------------------------
- // Handle any high level events (AppleEvents currently)
- static void DoHighLevelEvt(void)
- {
- DoAEvts(&gTheEvent);
- } // DoHighLevelEvt
-
-
- // ---------------------------------------------------------------------
- // Do idle processing
- static void DoIdle(void)
- {
- FSSpec aFile;
-
- // Check for timeout on startup message. Remove the dialog after timeout.
- if (SplashScreenShown()) // if screen still up..
- UpdateSplashScreen();
-
- // Keep Editor window cursor blinking
- SrcWindMaintainCursor();
-
- // take care of next drag-n-dropped file in the queue
- if (!gDoingBatchODOCs)
- if (FileQ_NumItems() > 0)
- if (FileQ_Get(&aFile))
- BatchProcessOneFile(&aFile);
- } // DoIdle
-
-
- // ---------------------------------------------------------------------
- // Do everything you ever need to do in the guts of a Mac event loop
- static void CheckForEvents(void)
- {
- // get next event
- WaitNextEvent(everyEvent, &gTheEvent, gDoingRender?gWNEReleaseTicks:30, NULL);
-
- // handle the event
- if (IsDialogEvent(&gTheEvent) && IsMModalDialogDisplayed())
- {
- HandleMModalDialogEvent(&gTheEvent);
- }
- else
- switch (gTheEvent.what)
- {
- case mouseDown:
- // If the startup screen is still up, kill it
- if (SplashScreenShown())
- KillSplashScreen();
- DoMouseDown();
- break;
-
- case keyDown:
- case autoKey:
- // If the startup screen is still up, kill it
- if (SplashScreenShown())
- KillSplashScreen();
- DoKeyDown();
- break;
-
- case diskEvt:
- DoDiskEvt(&gTheEvent);
- break;
-
- case updateEvt:
- DoUpdateEvt();
- break;
-
- case activateEvt:
- DoActivateEvt();
- break;
-
- case osEvt: // suspend/resume, mousemoved..
- DoOSEvt();
- break;
-
- case kHighLevelEvent: // AppleEvents
- DoHighLevelEvt();
- break;
-
- case nullEvent:
- default:
- break;
- }
-
- // do any idle processing
- DoIdle();
-
- } // CheckForEvents
-
-
- // ---------------------------------------------------------------------
- // Called from rendering engine, allows Mac code to breathe while the
- // renderer is parsing and rendering. This keeps menus working..
- // doImmediate if true will always breathe, otherwise it breathes every delta ticks.
- // APGet_TimeSlice() delta
- // ----------------- --------
- // 1 4<<1= 8
- // 2 4<<2= 16
- // 3 4<<3= 32
- // 4 4<<4= 64
- // 5 4<<5=128
- #pragma segment Main
- void Cooperate(int doImmediate)
- {
- int delta;
- volatile long stackCurr; // force it to be stack-based
-
- // do a quick stack depth check
- stackCurr = gStackBase-(long)&stackCurr; // address of stackCurr is approx. curr stack address
- if (stackCurr > gStackMax)
- gStackMax = stackCurr;
-
- // remember, this next line is: 4 shifted to the TimeSlice'th place,
- // so delta is 4*2=8,4*4=16,4*8=32, etc
- delta = 4 << APGet_TimeSlice();
- if ( doImmediate || (MAC_TICKS > gPrevTickCount + delta) )
- {
- // Update the clock before other applications
- // have breathed, so our time slices are more equally spaced
- gPrevTickCount = MAC_TICKS;
-
- // Now let other apps breathe
- CheckForEvents();
- }
- } // Cooperate
-
-
-
- // ------------------------------------------------------------------
- // loop for events to handle until the user quits the program
- #pragma segment Main
-
- static void MainEventLoop(void)
- {
-
- #ifdef DO_BETA
- if (gTimeoutFlag)
- {
- (void)DisplayModalDialog(rDlg_BetaTimeout, ok, 0, NULL, 0, ewcDoCentering, eMainDevice);
- SysBeep(4);
- }
- #endif // DO_BETA
-
- while (!AppIsQuitting())
- {
- Cooperate(true);
- if (gBeginRendering)
- DoRendering();
- }
- } // MainEventLoop()
-
-
- // ---------------------------------------------------------------------
- // Do any necessary cleanup prior to exiting (call here to cleanly exit)
- #pragma segment Main
- void exit_handler(void)
- {
- dispose_virtual(); /* close virtual file */
-
- KillImageWindow();
-
- KillOffscreen();
-
- FileQ_d(); // Tear down ODOC File Queue
-
- KillTemplateMenu();
-
- if (gSrcWind_VRefNum != 0) // if there is a file open..
- {
- FilePrefs_Write(gSrcWind_VRefNum, gSrcWind_FileName);
- // if file is dirty, save it automatically!
- // NOTE: This would only happen if we got a QUIT appleEvent, if the user
- // picked QUIT from the menu, we would have already prompted to save.
- if (gSrcWind_dirty)
- if (DoFile(fmn_close))
- ;
- }
-
- if (gAppPrefs_h)
- AppPrefs_Write();
-
- if (gtheSCComponent != NULL)
- {
- CloseComponent(gtheSCComponent);
- gtheSCComponent = NULL;
- }
-
- if (gp2wWindow)
- {
- p2w_DisposeWindow(gp2wWindow);
- gp2wWindow = NULL;
- }
- p2w_Terminate();
-
- SetAppQuit(); // must do this, Think C calls unexpected_exit (again) INSIDE ExitToShell!
- } // exit_handler
-
-
-
- // ---------------------------------------------------------------------
- // Called if unexpectedly aborting
- #pragma segment Main
- static void unexpected_exit(void)
- {
- // we are exiting within an error condition at this point...
- if (!AppIsQuitting())
- {
- if (gAppPrefs_h)
- {
- DisposeHandle((Handle) gAppPrefs_h);
- gAppPrefs_h = NULL;
- }
- // fatal error, exiting
- (void)DisplayModalDialog(132, ok, 0, NULL, 0, ewcDoCentering, eMainDevice);
- exit_handler();
- ExitToShell();
- }
- } // unexpected_exit
-
-
-
- // ---------------------------------------------------------------------
- // load all needed menus
- #pragma segment Inits
-
- static void SetupMenus()
- {
- int i;
- short anError = noErr;
-
- for (i = 0; (i < num_of_menus) && !anError; i++)
- {
- myMenus[i] = GetMenu(i + menu_offset);
- if (myMenus[i] == NULL)
- {
- anError = ResError();
- (void)DisplayModalDialog(kdlog_GenericFatalErr, ok, 0, "Cannot get main menu resource", i, ewcDoCentering, eMainDevice);
- SetAppQuit();
- break;
- }
- else
- {
- if (i==0) // add DA list to Apple menu
- AppendResMenu(myMenus[apmn_ID - menu_offset], 'DRVR');
- InsertMenu(myMenus[i], 0);
- }
- }
- for (i = 0; (i < num_of_submenus) && !anError; i++)
- {
- mySubMenus[i] = GetMenu(i + submenu_offset);
- if (mySubMenus[i] == NULL)
- {
- anError = ResError();
- (void)DisplayModalDialog(kdlog_GenericFatalErr, ok, 0, "Cannot get sub-menu resource", i, ewcDoCentering, eMainDevice);
- SetAppQuit();
- break;
- }
- else
- InsertMenu(mySubMenus[i], -1);
- }
- DrawMenuBar();
-
- // disable menus until we are ready...
- DisableMenus();
-
- } // SetupMenus
-
-
-
- // ------------------------------------------------------------------
- #pragma segment Inits
-
- static void InitAppGlobals(void)
- {
- // set up a full distribution message for display in splash screen and about box.
- gDistMessage = (StringPtr)NewPtr(256);
- strcpy((char*)gDistMessage, DISTRIBUTION_MESSAGE_1);
- strcat((char*)gDistMessage, " ");
- strcat((char*)gDistMessage, DISTRIBUTION_MESSAGE_2);
- strcat((char*)gDistMessage, " ");
- strcat((char*)gDistMessage, DISTRIBUTION_MESSAGE_3);
- c2pstr((char*)gDistMessage);
-
- /* create application prefs records */
- gAppPrefs_h = (app_prefs_hdl_t) NewHandle(sizeof(app_prefs_rec_t));
- MoveHHi((Handle) gAppPrefs_h);
- HLock((Handle) gAppPrefs_h);
-
- /* create default file settings record */
- gDefltFilePrefs_h = (file_prefs_hdl_t) NewHandle(sizeof(file_prefs_rec_t));
- MoveHHi((Handle) gDefltFilePrefs_h);
- HLock((Handle) gDefltFilePrefs_h);
-
- /* create file settings record */
- gFilePrefs_h = (file_prefs_hdl_t) NewHandle(sizeof(file_prefs_rec_t));
- MoveHHi((Handle) gFilePrefs_h);
- HLock((Handle) gFilePrefs_h);
-
- /* set up bounds for window dragging (multiple/big monitors) */
- SetRect(&gDragBounds, -16000, -16000, 16000, 16000);
-
- *gSrcWind_FileName = '\0';
- gRenderedOK = true;
-
- #if defined(__MWERKS__)
- _ftype = 'TEXT'; // from unix.mac.h
- _fcreator = 'ttxt'; // from unix.mac.h
- #endif
-
- }
-
-
-
- // ------------------------------------------------------------------
- #pragma segment Inits
-
- static void InitMoreAppStuff(void)
- {
- OSErr anError = noErr;
- PicHandle scPicH = NULL;
- Rect p2wRect;
-
- //
- // Set up application globals
- //
-
- InitAppGlobals();
-
- /* Register an exit handler */
- atexit(unexpected_exit);
-
- /* Read global settings from prefs file */
- if (!AppIsQuitting())
- AppPrefs_Read();
-
- //
- // Set up splash screen (after reading prefs!)
- //
-
- if (APGet_ShowSplashScreen())
- CreateSplashScreen();
-
- //
- // Set up application menus
- //
-
- SetupMenus();
-
- //
- // Install our AEvt handler routines for accepting docs dropped on app
- //
-
- if (!AppIsQuitting())
- InstallAppleEvents();
-
- //
- // set up an empty cursor region for use by WaitNextEvent
- //
-
- if (!AppIsQuitting())
- {
- gCursorRgn = NewRgn();
- }
-
- // See if the image compression manager is installed.
- if (gHasImageCompressionMgr)
- {
- // Install and open the standard compression dialog component.
- gtheSCComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
- if (gtheSCComponent)
- {
- // Initial defaults for SC compression dialog.
- (void)SCGetInfo(gtheSCComponent, scSpatialSettingsType, &(**gDefltFilePrefs_h).sc_DialogParams);
- scPicH = GetPicture(kDemoPICTrsrcID);
- // pick a preview pict for initializing the SC defaults
- if (scPicH)
- {
- // set default pict
- (void)SCDefaultPictHandleSettings(gtheSCComponent, scPicH, false);
- // get defaults the component set up
- (void)SCSetTestImagePictHandle(gtheSCComponent, scPicH,
- NULL, scPreferScalingAndCropping);
- }
- }
- }
-
- // Set up the status output window
- if (!anError)
- {
- anError = p2w_Init();
- if (!anError)
- {
- p2wRect = (**gDefltFilePrefs_h).statWind_pos;
- gp2wWindow = p2w_NewWindow(kWindID_p2w, &p2wRect, "\pPOV-Ray Status", true,
- monaco, 9, &anError);
- }
- if (anError)
- {
- (void)DisplayModalDialog(kdlog_P2W_INIT_ERROR, ok, 0, NULL, 0, ewcDoCentering, eMainDevice);
- exit_handler();
- }
- }
-
- // set up template menu
- if (!anError)
- {
- anError = InitTemplateMenu();
- if (anError)
- {
- // fatal error
- DisplayModalDialog(kdlog_GenericFatalErr, ok, 0, "Cannot create template menu",
- anError, ewcDoCentering, eMainDevice);
- exit_handler();
- }
- }
-
- // If user wants template menu pre-built, do it
- if ((!anError) && APGet_AutoTemplates())
- ImportTemplates();
-
- if (!anError)
- InitImageWindow();
-
- if (!anError)
- SetupPalettes();
-
- SetupStdModalFilter(); /* dialogutils */
-
- // initialize the ODOC File Queue
- if (!anError)
- FileQ_c();
-
- /* Figure out how much (or little) time to give other processes (oink) */
- CalcCpuReleaseTicks(false);
-
- // for text editor
- Init_Editor();
-
- // give the user some control!
- if (!anError)
- EnableMenus();
-
- // Display initial credit screen now
- // allocate some engine buffers so that screen output works.
- pre_init_povray();
- // tell POV-Ray engine to display default (author) screen, false=no terminate
- Usage(-1, false);
- // write our own Mac-specific credits
- PrintMacCredits();
-
- // dump initial debug/system information
- DisplayConfigInfo();
-
- } // InitMoreAppStuff()
-
-
-
- // ------------------------------------------------------------------
- // Check one bit in the long word passed, return TRUE if bit is on.
- #pragma segment Inits
-
- static Boolean CheckGestaltBit(unsigned long gestaltResponse, short gestaltBit)
- {
- return( (gestaltResponse & (1<<gestaltBit) ) != 0);
- } // CheckGestaltBit
-
-
-
- // ------------------------------------------------------------------
- #pragma segment Inits
-
- static void ValidateSystemConfig(void)
- {
- Boolean ConfigOK = true;
- OSErr gestaltErr = noErr;
- long gestaltResponse;
- char *errStr = NULL;
- #if !defined(powerc) && !defined (__powerc)
- long cpu68kType;
- #endif
- long sysArchitecture;
-
- //
- // Check system version stuff
- //
-
- if (errStr == NULL)
- {
- gestaltErr = Gestalt(gestaltSystemVersion, &gestaltResponse);
- if ((gestaltErr != noErr) || (gestaltResponse < 0x0700))
- errStr = "You do not have System 7.0 or newer.";
- }
-
- //
- // Check CPU stuff
- //
-
- if (errStr == NULL)
- {
- // See if we are running on 68K or PowerPC hardware architecture
- if (Gestalt(gestaltSysArchitecture, &sysArchitecture) == noErr)
- {
- #if defined(powerc) || defined (__powerc)
- // We're compiled for PowerPC, better be one
- if (sysArchitecture != gestaltPowerPC)
- errStr = "You do not have a recognized CPU type.";
- #else // !PowerPC
- // what kind of 68k CPU?
- Gestalt(gestaltProcessorType, &cpu68kType);
- #if defined (NEEDS_68020)
- if (cpu68kType < gestalt68020)
- errStr = "You do not have a 68020 or better CPU type.";
- #endif // NEEDS_68020
- // Here we are compiled for regular 68K Mac... see if we're really
- // running on a Power Mac and issue a friendly suggestion to use
- // the native PowerMac version... allow them to continue on anyway,
- // in case they can't get the POVPPC software (and they have SoftwareFPU running.)
- if (sysArchitecture == gestaltPowerPC)
- {
- DisplayModalDialog(kdlog_UsePPCVersion, ok, 0, NULL, cpu68kType, ewcDoCentering, eMainDevice);
- }
- #endif // else !PowerPC
- }
- }
-
- //
- // Check FPU stuff (only on 68k, PowerPC always has FPU)
- //
-
- #if !defined(powerc) && !defined (__powerc)
- if (errStr == NULL)
- {
- if (Gestalt(gestaltFPUType, &gestaltResponse) == noErr)
- {
- #if defined (NEEDS_FPU)
- // If this was compiled to REQUIRE FPU, get error if no FPU installed
- if (gestaltResponse == gestaltNoFPU)
- errStr = "You do not have a 68881/68882 Floating Point Unit.";
- #else
- // if compiled to not need FPU, give warning if running on FPU machine,
- // tell user there is a better software option (POVFPU)
- if (gestaltResponse != gestaltNoFPU)
- DisplayModalDialog(kdlog_UseFPUVersion, ok, 0, NULL, 0, ewcDoCentering, eMainDevice);
- #endif // NEEDS_FPU
- }
- }
- #endif // powerc
-
- // Check Quickdraw stuff
- gHas32BitQD = false;
- gHasPictUtils = false;
- if (errStr == NULL)
- {
- if (Gestalt(gestaltQuickdrawVersion, &gestaltResponse) == noErr)
- {
- gHas32BitQD = (gestaltResponse >= gestalt32BitQD);
- gHasPictUtils = gHas32BitQD;
- #if defined (NEEDS_32BITQD)
- if (!gHas32BitQD)
- errStr = "You do not have 32 Bit Color Quickdraw.";
- #endif // NEEDS_32BITQD
- }
- }
-
- // Check QuickTime version
- gHasQuickTime = false;
- gHasImageCompressionMgr = false;
- if (errStr == NULL)
- {
- if (Gestalt(gestaltQuickTime, &gestaltResponse) == noErr)
- {
- gQTVersion = gestaltResponse;
- if (gQTVersion >= 0x01608000 // at least version 1.6 final
- #if defined(powerc) || defined (__powerc)
- // weak link, see if QT lib is installed
- && ((ProcPtr)SCPositionDialog != (ProcPtr)kUnresolvedCFragSymbolAddress)
- #endif
- )
- {
- gHasQuickTime = true;
- // Check QuickTime Compression stuff
- if (Gestalt(gestaltCompressionMgr, &gestaltResponse) == noErr)
- gHasImageCompressionMgr = CheckGestaltBit(gestaltResponse, 4);
- }
- #if defined(powerc) || defined (__powerc)
- // handled with weak link check above
- // // Check PPC QuickTime lib present
- // if (Gestalt(gestaltQuickTimeFeatures, &gestaltResponse)==noErr)
- // if (!CheckGestaltBit(gestaltResponse, gestaltPPCQuickTimeLibPresent))
- // errStr = "You do not have QuickTime PPC Shared Library installed.";
- #endif
- }
- }
-
- // Check AppleEvent stuff
- gHasAppleEvents = false;
- if (errStr == NULL)
- {
- if (Gestalt(gestaltAppleEventsAttr, &gestaltResponse) == noErr)
- gHasAppleEvents = CheckGestaltBit(gestaltResponse, gestaltAppleEventsPresent);
- if (!gHasAppleEvents)
- errStr = "You do not have AppleEvents.";
- }
-
- // Show any initialization errors now
- if (errStr != NULL)
- { // insufficient hardware/software config..
- DisplayModalDialog(kdlog_ConfigFatalErr, ok, 0, errStr, 0, ewcDoCentering, eMainDevice);
- exit_handler();
- SetAppQuit();
- }
-
- } // ValidateSystemConfig()
-
-
-
- // ------------------------------------------------------------------
-
- static void ValidateAppConfig(void)
- {
-
- //
- // Is our app intact? Check some key resources... if we are corrupt,
- // we probably don't want to bring up any (corrupt) dialogs, so again
- // we simply beep twice and exit. This would be a great place to do a
- // checksum on our CODE #0 resource and report virus infection!
- //
- /*
- if (GetNewMBar(eMenuBar) == NULL)
- {
- SysBeep(2);
- SysBeep(2);
- SetAppQuit();
- }
- */
- } // ValidateAppConfig()
-
-
-
- // ------------------------------------------------------------------
- // Allocate more memory for stack before doing much heap stuff,
- // for 68K Macs anyway. PPC Macs have a 36 double D stack area,
- // and therefore don't need any artificial enlargement. Also, this
- // System 6 style retro-tweaking is bad for Copland! [esp]
-
- // No, segment 'Main' is not a bug, heap stuff must happen before any code segment loads,
- // so we have to do this all in the "Main" segment.
- #pragma segment Main
-
- static void InitHeap(void)
- {
- volatile long stk_size; // force it to be a stack variable
- #if !defined(powerc) && !defined (__powerc)
- app_config_hdl_t app_config_h;
-
- app_config_h = (app_config_hdl_t)Get1Resource(kAppConfigRsrc, kAppConfigRsrcID);
- if (app_config_h)
- {
- // stackSize - # of bytes to grow the stack to (for recursion)
- // [10k < stk_size < 150k]
- stk_size = (**app_config_h).stackSize;
- if (stk_size <= 10000L)
- stk_size = 10000L;
- else if (stk_size > 150000L)
- stk_size = 150000L;
-
- // all done with this
- ReleaseResource((Handle)app_config_h);
- }
- else
- { // set to default values
- stk_size = DEFAULT_STACK_SIZE;
- }
- SetApplLimit(GetApplLimit() - stk_size);
- #endif
-
- //
- // Now grow the heap out to its max extent
- //
-
- MaxApplZone();
-
- //
- // Make sure we have enough free memory to run. Unfortunately this is
- // so early in initialization that we can't put up any dialogs (no tools),
- // instead we just beep once to let the user know something is amiss.
- //
-
- #define MIN_FREEMEM_OK 800*1024L // for this app, 800K free is a bare minimum
- if (FreeMem() < MIN_FREEMEM_OK)
- {
- SysBeep(1);
- SetAppQuit();
- }
- else
- {
- // allocate malloc() safety buffer
- AllocateSafetyBuffer(RESERVE_MEM_SIZE);
- }
-
- //
- // Get current value of stack to compare against later
- gStackBase = (long)&stk_size;
-
- } // InitHeap()
-
-
- // ------------------------------------------------------------------
- // Initialize all the Macintosh toolboxes we need..
- #pragma segment Inits
-
- static void InitToolbox(void)
- {
- EventRecord anEvent;
- short count;
-
- gAppRefNum = CurResFile();
-
- //
- // Init all the basic tools
- //
-
- InitGraf( (Ptr)&qd.thePort );
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(0L);
-
- //
- // Set up the cursor, and set it initially to a watch cursor
- //
-
- InitCursor();
- InitWatchCursor();
- ShowWatchCursor();
-
- //
- // Allocate some extra master pointers to avoid mem. fragmentation
- //
-
- for (count=0; count<10; count++)
- MoreMasters();
-
- //
- // DTS Hocus Pocus to bring our app to the front
- //
-
- for (count = 1; count <= 3; count++)
- {
- EventAvail(everyEvent, &anEvent);
- // while we're here, see if option key was down on launch
- // gOptionKeyDownOnStartup = ((anEvent.modifiers & optionKey) != 0);
- }
-
- } // InitToolbox()
-
-
-
- // ------------------------------------------------------------------
- // One-time initialization of application-specific stuff
- #pragma segment Main
-
- static void InitializeApp(void)
- {
- #ifdef DO_BETA
- time_t theTime;
- time(&theTime);
- gThetmPtr = localtime(&theTime); // get todays date
- #endif // DO_BETA
-
- gQuit = false;
-
- //
- // Set up application heap
- //
-
- InitHeap();
-
- //
- // Initialize Mac toolbox routines
- //
-
- if (!AppIsQuitting())
- InitToolbox();
-
- //
- // Is our application intact, or did ResEdit or Virii munge our resources?
- //
-
- if (!AppIsQuitting())
- ValidateAppConfig();
-
- //
- // Do we have the right MacOS System configuration?
- //
-
- if (!AppIsQuitting())
- ValidateSystemConfig();
-
- //
- // Do the final application initialization
- //
-
- if (!AppIsQuitting())
- InitMoreAppStuff();
-
- ShowArrowCursor();
-
- } // InitializeApp()
-
-
-
- // ------------------------------------------------------------------
- // Handle anything as the app quits
- #pragma segment Main
-
- static void TerminateApp(void)
- {
-
- //
- // close up
- //
-
- exit_handler();
-
- } // TerminateApp()
-
-
-
- // ------------------------------------------------------------------
- #pragma segment Main
- int main(void)
- {
-
- #if defined(applec)
- //
- // MPW has unpacked our initialized global area, unload their code segment
- //
- UnloadSeg((ProcPtr) _DataInit);
- #endif // applec
-
- //
- // initialize application (memory, toolbox, globals)
- //
-
- InitializeApp();
-
- #ifdef DO_BETA
- // If it is beyond timeout date, disable ourselves
- if (gThetmPtr->tm_year >= BETA_YEAR)
- if (gThetmPtr->tm_mon >= BETA_MONTH-1)
- if (gThetmPtr->tm_mday >= BETA_DAY)
- gTimeoutFlag = 2.10; // this will be set to 0.0 if OK to run
- #endif // DO_BETA
-
-
- #if defined(applec)
- UnloadSeg((ProcPtr) InitToolbox);
- #endif // applec
-
- //
- // Handle user input until quit
- //
-
- if (!AppIsQuitting())
- {
- MainEventLoop();
- }
-
- //
- // Heading out, clean up
- //
-
- TerminateApp();
-
- return(0); // be nice to Mr. ANSI, he's our friend
-
- } // main()
-